DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

diff 内容相同,rsync 仍重复列出待更新文件

diff 内容相同而 rsync 仍列出待更新文件时,用 -i 分辨传输和属性更新,再用校验和预演核对修改时间差异,保留必要的备份属性。

diff 看不出文件内容差异,rsync -a --dry-run 却仍把文件列为待更新项。这不一定是内容比较出错:rsync 默认先比较文件大小和修改时间;使用 -a 时,权限、属主等需要保留的属性也会影响更新计划。

下面针对 rsync 3.x 的普通文件同步。先在稳定、可读的源目录和目标目录上做预演,分清内容传输与属性更新,再决定是否改变同步选项。运行期间仍有程序写文件时,前后两次检查可能看到不同状态。

用 -i 看清待更新的部分

将原命令保留为预演,并加上 -i:

rsync -ani -- ./source/ ./destination/

./source/ 和 ./destination/ 是需要替换的目录占位值,源目录末尾的 / 表示同步目录里的内容。-n 不实际修改目标,-i 给每个条目标出变化类型;这里只用本地路径展示判断方法,远程同步也可在原命令上添加这两个选项。

普通文件的标记中,第二位 f 表示文件,后面的 s、t、p 分别表示大小、修改时间、权限需要更新。例如,看到下面这样的标记:

>f..t...... report.txt

其中 t 表示修改时间不同,开头 > 表示文件计划向本地接收端传输。不能因为只有 t 就把整条输出解释成“肯定只改元数据”:默认检查发现时间不同,也可能将内容相同的文件选入传输。

相反,首位为 . 时,没有安排该条目的内容更新,但仍可能修改属性。例如 .f...p..... 表示普通文件的权限需要更新。判断时同时看首位和属性位,不能只看文件名是否出现在列表里。

diff 比较的是文件内容,不会替你确认修改时间、权限或属主一致,因此它与上述更新计划并不矛盾。

用一次校验和预演区分内容与时间

如果怀疑只是修改时间不同,可以在同一组稳定路径上增加 -c:

rsync -acni -- ./source/ ./destination/

-c 把传输前的内容选择改成大小与校验和检查。大小相同的文件需要读取内容生成校验和,不再仅凭修改时间不同决定是否传输。两端大量文件都要读盘,这次预演本身也可能较慢;应先对受影响的小范围检查,避免在繁忙目录上反复全量扫描。

若文件校验和一致、只是时间不同,内容传输标记可以消失,而 t 仍可能保留。原因是 -a 包含 -t,仍要求目标修改时间与源一致。-c 没有关闭这项属性同步,也不会自动忽略权限差异。

这项校验与 rsync 正常传输完成后验证接收文件的校验不同:这里改变的是传输前“是否需要传这个文件”的判断。不要把未加 -c 理解成传输后完全不校验。

根据备份要求处理,而不是只让列表变空

如果源目录是权威副本,目标本来就应保留它的时间和权限,那么时间不同并不需要绕过。核对预演里的目录、文件和属性后,在目标已有可恢复备份的前提下,才考虑实际同步。下面保留校验和判断,但移除了预演选项:

rsync -aci -- ./source/ ./destination/

这条命令会写入目标,也会按 -a 的要求尝试更新属性;它不是只读检查。不要在未核对同步方向、覆盖范围和属性要求时直接照抄。目录内容和元数据都需要有恢复途径,尤其不能把“字节没有变化”当成权限调整没有风险。

如果日常任务无需每次读取内容计算校验和,而且目标能正确保存修改时间,日常任务可以继续用原来的 -a 快速检查。修正的是导致时间反复变化的流程,例如每次生成相同内容时仍重写文件,而不是把 -c 当作所有同步任务的固定配置。

若目标文件系统不能表示源端某些属性,或者运行账号没有设置这些属性的权限,应根据具体错误调整同步契约。不要为了消除一条 p 就全面放宽权限,也不要直接改用 --size-only:同大小文件也可能有不同内容。只允许较少时间精度的目标,需要先确认文件系统精度再决定比较容差,不能把所有重复传输都归为时间精度问题。

完成后再次检查同一范围

实际同步成功后,再运行相同的 -acni 预演。若源和目标保持不变、要求保留的属性也都成功设置,刚才的更新项应消失。仍有条目时,根据标记分别检查内容变化、时间重写和属性设置错误,并查看上一次命令的退出状态。

预演成功不能保证随后写入一定成功,磁盘空间、权限及并发写入仍可能使实际任务失败。回退时使用同步前备份恢复被覆盖的文件及其必要元数据;重新运行相反方向的 rsync 不是可靠的撤销方式。