我正在使用 rsync 通过 SSH 将文件从 Linux 复制到 Mac。
我的命令如下:
rsync \
--exclude FOO \
--exclude BAR \
-e ssh \
-rclpvih \
--delete \
--stats \
/local/dir/ \
host:/remote/dir/
输出如下:
building file list ... done
...
<fc.T...... core/FileRecordingProcessor.cpp
<fc.T...... core/Pipeline.hpp
...
Number of files: 4,910 (reg: 4,401, dir: 509)
Number of created files: 0
Number of regular files transferred: 35
Total file size: 332.34M bytes
Total transferred file size: 2.62M bytes
Literal data: 0 bytes
Matched data: 2.62M bytes
File list size: 196.59K
File list generation time: 0.457 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 209.72K
Total bytes received: 12.03K
sent 209.72K bytes received 12.03K bytes 147.83K bytes/sec
total size is 332.34M speedup is 1,498.70
即使本地没有任何变化,rsync 也会在每次调用时传输相同的文件(子)集。
这些文件只是整个树的一小部分。其他文件除非确实发生更改,否则不会重新发送。重新发送的文件数始终为 35 个。所有文件都有<fc.T......
标志。
文件在本地和远程机器上看起来完全相同。
当地的:
$ ll core/Pipeline.hpp
-rw-r--r-- 1 victor victor 5.1K Nov 2 18:24 core/Pipeline.hpp
$ md5sum core/Pipeline.hpp
7604940d777322a587d2fe2fa12c1183 core/Pipeline.hpp
偏僻的:
$ ll core/Pipeline.hpp
-rw-r--r-- 1 victor staff 5.1K Nov 3 18:20 core/Pipeline.hpp
$ md5sum core/Pipeline.hpp
7604940d777322a587d2fe2fa12c1183 core/Pipeline.hpp
所有者、组和时间不一样,但 rsync 未配置为保留它们,而是配置为使用校验和。
两台机器的时间不同步。
答案1
发生这种情况的一种情况是当 rsync 在区分大小写的文件系统(通常是 Linux)和不区分大小写的文件系统(通常是 Windows 和 MacOS)之间传输文件时。
如果同步的两个路径(例如d/x
和d/X
)在名义上转换为小写之后相同,则 rsync 不会注意到,并且可能会传输d/x
,然后用覆盖相同的目标文件d/X
。
如果文件不包含相同的数据,但具有相同的时间戳,则文件将在未来 rsync 运行时始终更新。
我建议检查一下大小写差异是否导致 rsync 错误地重新传输文件。一个有用的 Linux 命令是:
find . | tr '[:upper:]' '[:lower:]' | LC_ALL=C sort | LC_ALL=C uniq -d
答案2
您缺少--archive
( -a
) 或--times
( -t
) 标志。如果没有其中一个,rsync
则不会跟踪更改时间,因此无法绕过看起来已被复制的文件
您还明确告知rsync
使用校验和来验证文件是否已被复制,所以这就是所做的rsync
。
一般来说,--archive
( -a
) 标志几乎可以满足您的所有需求:
rsync --exclude FOO --exclude BAR -avi --delete --stats /local/dir/ host:/remote/dir/
您可能需要添加-H
以保留硬链接(如果有),以及-AX
保留 ACL 和扩展属性(如果有)。
答案3
TL;DR:如果您使用的是 macOS,请尝试使用 /usr/bin/rsync,而不是“brew”或“nix”或其他系统可能安装的开源 rsync。本机 rsync 更好地理解 Apple 的特殊文件系统,并且不会重新复制未更改的文件。
较长的版本...
如果您使用的版本不支持特定于操作系统的情况,则可能会发生这种情况rsync
。它将重新复制它认为已更改但实际上没有更改的文件。
例如,我的 Mac 有两个版本rsync
:
$ which -a rsync
/usr/local/bin/rsync
/usr/bin/rsync
/usr/local/bin/rsync
是版本 3.2.4,支持协议版本 31。我使用“brew”安装了它。
/usr/bin/rsync
是 Apple 提供的版本,它是从 2.6.9 版本(更旧)分叉而来的,并支持协议版本 29。Apple 对此版本进行了增强,以支持特定于 macOS 的文件系统功能。
当我使用-c
开源版本时,会重新复制未更改的文件。Apple 提供的 rsync 没有这个问题。
虽然协议版本 29 和 31 之间有很多优化,但您可能不会错过它们。使用 Apple 的 rsync 确保一切正确可能很重要。
答案4
我最终切换到齐奏用于 Linux 和 macOS(以及 Windows)之间的同步:
unison \
-servercmd /usr/local/bin/unison
-ignore "Name FOO" \
-ignore "Name BAR" \
-auto \
-batch \
-force /local/dir/ \
/local/dir/ \
ssh://host/remote/dir/