為什麼 rsync 每次呼叫都會發送相同的檔案?

為什麼 rsync 每次呼叫都會發送相同的檔案?

我正在使用 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/xd/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 有 2 個版本rsync

$ which -a rsync
/usr/local/bin/rsync
/usr/bin/rsync

/usr/local/bin/rsync是版本 3.2.4,支援協定版本 31。

/usr/bin/rsync是 Apple 提供的版本,它是從版本 2.6.9(較舊的版本)分叉出來的,支援協定版本 29。

當我使用-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/

相關內容