You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rsync配置需求:校验和相同时保留目标文件原时间戳

如何让rsync仅在文件内容不同时更新目标文件及其时间戳

我明白你的需求:想用rsync同步目录,但希望内容完全一致的文件保留目标端的原时间戳,只有当内容真的变化时,才更新文件并同步源文件的时间戳。咱们一步步拆解问题和解决方案:

问题场景

初始状态下,两个文件内容一致但时间戳不同:

~/Homepage $ ls -l harp_output/BingSiteAuth.xml harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 07:58 harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 08:10 harp_output/BingSiteAuth.xml

用cmp验证内容完全一致:

~/Homepage $ cmp harp_output/BingSiteAuth.xml harp_netlify/BingSiteAuth.xml; echo $?
0

你执行了这条rsync命令:

~/Homepage $ rsync -cav --delete harp_output/ harp_netlify/

结果却发现,内容一致的文件时间戳还是被同步成了源文件的:

~/Homepage $ ls -l harp_output/BingSiteAuth.xml harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 08:10 harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 08:10 harp_output/BingSiteAuth.xml

而你期望的是:

~/Homepage $ ls -l harp_output/BingSiteAuth.xml harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 07:58 harp_netlify/BingSiteAuth.xml
-rw-r--r-- 1 david david 81 14. Mai 08:10 harp_output/BingSiteAuth.xml

问题根源

问题出在rsync的-a(归档模式)参数上——它包含了-t(--times)选项,这个选项的作用是强制把目标文件的修改时间同步成源文件的,不管内容是否相同。哪怕你加了-c(--checksum)让rsync用校验和判断内容一致性,-t依然会“固执地”同步时间戳,哪怕内容完全没变化。

解决方案

遗憾的是,rsync没有直接的单参数组合能完美满足你的需求,但我们有两种可行的方式:

方案1:用Shell脚本实现精确需求

这个脚本会严格按照你的要求执行:内容一致则保留目标时间戳,内容不同则同步文件和时间戳,同时处理删除操作:

#!/bin/bash

# 定义源目录和目标目录
SOURCE_DIR="harp_output/"
DEST_DIR="harp_netlify/"

# 递归遍历源目录的所有文件
find "$SOURCE_DIR" -type f | while read -r src_file; do
    # 转换为目标文件路径
    dest_file="${src_file/$SOURCE_DIR/$DEST_DIR}"
    
    # 如果目标文件不存在,直接同步(包含时间戳)
    if [ ! -f "$dest_file" ]; then
        rsync -av "$src_file" "$dest_file"
        continue
    fi
    
    # 计算源文件和目标文件的SHA256校验和(也可以换成md5sum)
    src_sum=$(sha256sum "$src_file" | awk '{print $1}')
    dest_sum=$(sha256sum "$dest_file" | awk '{print $1}')
    
    # 校验和不同时,同步文件和时间戳
    if [ "$src_sum" != "$dest_sum" ]; then
        rsync -av "$src_file" "$dest_file"
    fi
done

# 删除目标目录中源目录不存在的文件
rsync -av --delete --dry-run "$SOURCE_DIR" "$DEST_DIR" | grep 'deleting' | awk '{print $2}' | while read -r del_file; do
    rm -f "${DEST_DIR}${del_file}"
done

把这个脚本保存为sync_with_checksum.sh,赋予执行权限(chmod +x sync_with_checksum.sh)后运行即可。

方案2:折衷的rsync参数组合

如果你不想写脚本,可以用两条rsync命令接近你的需求:

第一条命令同步文件,但不强制同步时间戳(用-rlpgoD代替-a,去掉-t):

rsync -crlpgoDv --delete harp_output/ harp_netlify/

这条命令会:

  • 内容一致的文件不会被传输,目标时间戳保持不变
  • 内容不同的文件会被传输,但目标时间戳是rsync执行的时间,不是源文件的时间戳

如果需要同步更新文件的时间戳,再执行第二条命令:

rsync -crtv --delete --existing harp_output/ harp_netlify/

这条命令会仅同步那些已存在且内容不同的文件的时间戳(--existing会忽略目标目录中没有的文件)。


内容的提问来源于stack exchange,提问作者duxsco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:46:08