Rsync: —— size-only 和——忽略-times 之间的差异

我想知道两种选择有什么区别

rsync --size-only

还有

rsync --ignore-times

我的理解是,默认情况下,rsync 将比较时间戳和文件大小,以决定是否应该同步文件。上面的选项允许用户影响此行为。

这两个选项似乎,至少在口头上导致了相同的结果: 只按大小比较

我是不是漏掉了什么微妙的东西?

130352 次浏览

Rsync 比较文件有几种方式——权威的来源是 rsync 算法描述: https://www.andrew.cmu.edu/course/15-749/READINGS/required/cas/tridgell96.pdf。Rsync 上的 维基百科文章也非常好。

对于本地文件,rsync 比较元数据,如果它看起来不需要复制文件,因为源文件和目标文件的大小和时间戳匹配,则不会进一步查看。如果不匹配,就是 cp。但是,如果元数据确实匹配,但是文件实际上不相同,该怎么办?那么 rsync 可能没有达到你的目的。

大小相同的文件可能仍然发生了更改。一个简单的例子是一个文本文件,您可以在其中更正一个输入错误——比如将“ teh”更改为“ the”。文件大小相同,但更正后的文件将有一个更新的时间戳。--size-only表示“不要看时间; 如果大小匹配,则假定文件匹配”,在这种情况下,这将是错误的选择。

另一方面,假设您昨天不小心做了一个大的 cp -r A B,但是您忘记保留时间戳,现在您想在反向 rsync B A中执行操作。所有 cp 过的文件都有昨天的时间戳,即使它们昨天并没有被修改,rsync 默认情况下会复制所有这些文件,并将时间戳更新到昨天。在这种情况下,--size-only可能是你的朋友(模上面的例子)。

--ignore-times说不管文件是否有相同的修改时间,都要比较这些文件。考虑上面的输入错误示例,然后不仅更正了输入错误,而且使用 touch使得更正后的文件与原始文件具有相同的修改时间——这么说吧,您这样做很狡猾。那么 --ignore-times将做一个差异的文件 即使的大小和时间匹配。

Rsync 还可以通过校验和比较文件,这一点没有考虑到。

--size-only意味着即使时间戳不同,rsync 也会跳过大小匹配的文件。这意味着它将比默认行为同步更少的文件。它将丢失任何不影响整个文件大小的更改文件。如果您有可以在不更改文件的情况下更改文件日期的内容,并且您不希望 rsync 花费大量时间对这些文件进行校验求和以发现它们没有更改,那么可以使用这个选项。

--ignore-times意味着 rsync 将对每个文件进行校验和,即使时间戳和文件大小匹配。这意味着它将同步比默认行为更多的文件。它将包括对文件的更改,即使文件大小相同,并且修改日期/时间已经重置为原始值。对每个文件进行校验求和意味着必须完全从磁盘读取文件,这可能比较慢。有些构建管道会将时间戳重置为特定的日期(比如1970-01-01) ,以确保最终的构建文件是可以一位一位地重现的,例如,当打包到一个 tar 文件中时,可以保存时间戳。

在 Scientific Linux 6.7系统上,rsync 的手册页显示:

--ignore-times          don't skip files that match size and time

我有两个内容相同但创建日期不同的文件:

[root@windstorm ~]# ls -ls /tmp/master/usercron /tmp/new/usercron
4 -rwxrwx--- 1 root root 1595 Feb 15 03:45 /tmp/master/usercron
4 -rwxrwx--- 1 root root 1595 Feb 16 04:52 /tmp/new/usercron


[root@windstorm ~]# diff /tmp/master/usercron /tmp/new/usercron
[root@windstorm ~]# md5sum /tmp/master/usercron /tmp/new/usercron
368165347b09204ce25e2fa0f61f3bbd  /tmp/master/usercron
368165347b09204ce25e2fa0f61f3bbd  /tmp/new/usercron

对于 --size-only,这两个文件被视为相同的:

[root@windstorm ~]# rsync -v --size-only -n  /tmp/new/usercron /tmp/master/usercron


sent 29 bytes  received 12 bytes  82.00 bytes/sec
total size is 1595  speedup is 38.90 (DRY RUN)

对于 --ignore-times,这两个文件被视为不同的:

[root@windstorm ~]# rsync -v --ignore-times -n  /tmp/new/usercron /tmp/master/usercron
usercron


sent 32 bytes  received 15 bytes  94.00 bytes/sec
total size is 1595  speedup is 33.94 (DRY RUN)

所以看起来 --ignore-times根本没有任何作用。

简短的回答是,--ignore-times所做的比它的名字所暗示的要多,它忽略了 都有的时间和大小。 相比之下,--size-only完全按照它所说的做。


较长的回答是,rsync有三种方法来判断一个文件是否过时:

  1. 比较源和目标的大小。
  2. 比较源和目的地的时间戳。
  3. 比较源和目标的静态校验和。

这些检查在传输数据之前执行。值得注意的是,这意味着静态校验和不同于流校验和——后者是在传输数据时计算的。

默认情况下,rsync仅使用1和2。一个 stat可以同时获取1和2,而3需要读取整个文件(这与读取要传输的文件无关)。假设只指定了一个修饰符,这意味着:

  • 通过使用 --size-only,只执行1-时间戳和校验和被忽略。除非文件两端的大小相同,否则将复制该文件。

  • 通过使用 --ignore-times,不会执行1、2或3。总是复制一个文件。

  • 通过使用 --checksum,在 加法到1中使用3,但是在执行 没有时使用2。除非大小和校验和匹配,否则将复制文件。只有在大小匹配时才计算校验和。