如何在 Linux 中使用 rsync 傳輸檔案

作者 | 劉光錄

來源 | TIAP

rsync(遠端同步,Remote Sync)是一種在系統中或兩個系統之間複製檔案和目錄的同步工具。rsync 的一個最大的優點,就是它只複製更改的檔案,因而可以減少 CPU 消耗,在複製檔案時節省頻寬和時間。

rsync 相比於 scp 的優點

我們大家可能知道 scp(secure copy 的簡寫),也是一個通過 ssh 在兩個遠端系統之間複製檔案的工具。但是 rsync 更好用,表現在以下三個方面:

1)rsync 只複製更改的檔案,而 scp 會複製所有的每個檔案,並且會覆蓋舊的檔案,因此,rsync的速度更快;

2)rsync 也可以在沒有加密的情況下工作,這可以減少系統開銷(僅用作對加密傳輸沒要求的情況下,有安全風險時慎用);

3)rsync 支持斷點續傳(但是scp不可以)。

在大多數Linux發行版中,rsync 默認是沒有安裝的,因此需要手動安裝。在 Ubuntu 和 Debian 系統中,可以使用如下命令安裝:

    sudo apt install rsync

    rsync 命令示例

    rsync命令的結構如下:

      rsync [OPTIONS] Source Destination

      上述命令中 Source 為檔案的源地址,Destination 為目的地址。源地址和目的地址可以是本地路徑也可以是遠端路徑,格式為:username@hostname:path/to/file

      我們接下來看幾個實際的例子。

      注意:假如我們有一個目錄 A,那麼 A 和 A/ 是不一樣的。A/ 指的是在目錄A下的所有檔案,但是不包括 A 本身;所以 複製 A 會在目的地址新建一個目錄,然後複製 A 中的檔案。但是複製 A/ 只會將 A 中的檔案複製到目的地址中。

      1. 同步本地檔案(單向同步)

      我們假設要將檔案從目錄A複製到Backup-A-dir中:

        rsync A/ Backup-A-dir/

        上述命令會將 A 中的檔案複製到 Backup-A-dir 中。但Backup-A-dir中的檔案不會同步到A中,這就是為什麼會被稱為單向同步的原因。

        2. 同步遠端檔案(單向同步)

        遠端系統和本地系統之間同步檔案,命令是類似的。注意,源地址和目的地址都可以是本地檔案系統路徑或者遠端系統(ssh)路徑。

          rsync dev/build username@hostname:~/Backup

          3. 雙向同步

          上述命令是將檔案從源地址複製到目的地址。我們假設有這樣一種情況,就是在目的地址中存在一些額外檔案,但是這些額外檔案在源地址中並不存在,那麼在單向同步的時候,不會將目的地址中的這些額外檔案刪掉。如果我們想要在同步的時候刪掉目的地址中的這些額外檔案(也就是需要與源地址中的檔案保持絕對一致),那麼就需要使用雙向同步。

          要保持源地址和目的地址中的檔案一致,將 –delete 選項添加到命令中即可:

            rsync A/ Backup-A-dir/ --delete

            4. 複製完成後刪掉源檔案

            如果要在複製完成後,刪掉源檔案,需要在命令中添加 –remove-source-files 選項:

              rsync A/ Backup-A-dir/ --remove-source-files

              刪掉源檔案需要慎重,要確保已經保存好了備份,並且待刪資料已經沒有用了。

              5. 「包括」和「排除」檔案

              如果你需要(或者不需要)傳輸某些指定的檔案,可以使用 –include 或者 –exclude 選項,後面跟上 = 和 指定檔案的模式表達式:

                rsync A/ Backup-A-dir/ --include=*.py --exclude=*.tmp.py

                以上命令會傳輸所有以 .py 作為後綴名的檔案,排除掉所有以 .tmp.py 為後綴名的檔案。

                上面提到的模式表達式,可以是正規表示式。

                注:如果 include 或 exclude 的檔案列表比較長,可以將其儲存在檔案中,使用的時候將檔案名稱傳遞給 –include-from 或者 –exclude-from 選項。

                6. 通過 ssh 傳輸

                如果想要通過 ssh 傳輸檔案,那麼需要使用 -e 選項來指定 ssh:

                  rsync -e ssh A/ username@hostname:~/Backup-A-dir/

                  這是傳輸檔案到遠端系統的首選方式,因為它傳輸的時候是加密的。需要注意的是,由於是加密傳輸,會產生系統開銷,所以這比正常傳輸更耗時。

                  要使用 ssh 傳輸,還需要確保伺服器端已經配置了ssh。

                  7. 詳情模式

                  Linux 中的大多數命令都會有詳情選項,用於在終端中記錄命令的操作。rsync 也不例外。

                  使用 -v 或者 -verbose 選項來顯示詳情,它會列出正在執行的操作和進度。這在調試的時候很方便。

                    rsync A/ Backup-A-dir/ -v -r

                    其輸出類似於如下的輸出:

                      $ rsync A/ Backup-A-dir/ -v -rsending incremental file listcreated directory Backup-A-dir./file1.txtfile2.txtfile3.txtfile4.txtfile5.txtfile6.txtsent 388 bytes received 168 bytes 1,112.00 bytes/sectotal size is 0 speedup is 0.00

                      8. 只運行(運行但是不執行復制操作)

                      如果你只是想知道在不進行實際傳輸的情況下,需要複製的檔案,那麼可以使用 –dry-run(或者 -n)選項:

                      除複製部分外,它與正常rsync命令一樣執行所有操作。它將列出要複製或刪除的檔案(如果需要),然後在複製之前停止。

                        $ rsync -v A/ Backup-A-dir/ –dry-runsending incremental file listcreated directory Backup-A-dir./file1.txtfile2.txtfile3.txtfile4.txtfile5.txtfile6.txtsent 172 bytes received 72 bytes 488.00 bytes/sectotal size is 0 speedup is 0.00 (DRY RUN)

                        注意,上述命令需要帶有參數 -v 來顯示詳情,否則不會顯示任何結果。

                        9. 顯示傳輸進度

                        要顯示傳輸進度,可使用 –progress 選項:

                          rsync A/ Backup-A-dir/ --progress

                          上面的命令將顯示一個類似於下面的進度條:

                            $ rsync -r A/ Backup-A-dir/ –progresssending incremental file listcreated directory Backup-A-dir./file1.txt 0 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=5/7)file2.txt 0 100% 0.00kB/s 0:00:00 (xfr#2, to-chk=4/7)file3.txt 0 100% 0.00kB/s 0:00:00 (xfr#3, to-chk=3/7)file4.txt 0 100% 0.00kB/s 0:00:00 (xfr#4, to-chk=2/7)file5.txt 0 100% 0.00kB/s 0:00:00 (xfr#5, to-chk=1/7)file6.txt 0 100% 0.00kB/s 0:00:00 (xfr#6, to-chk=0/7)

                            10. 壓縮和傳輸資料

                            使用 -z 選項可以壓縮要傳輸的資料,壓縮後在傳輸資料會更加節省網路頻寬和時間。它將在目的地自動解壓縮。

                            當傳輸的資料量很大時,使用 -z 選項進行壓縮會節省時間,但是對於小檔案,應該避免使用 -z,因為處理壓縮的開銷會超過正常情況下的時間。

                              rsync -z A/ Backup-A-dir/

                              11. 遞迴複製檔案和目錄

                              以上所有命令只複製檔案,不復制子目錄(每個Linux命令都是這樣)。因此,不會複製這些子目錄中的檔案。要複製子目錄中的檔案,可以使用 -r 選項。

                                rsync -r A/ Backup-A-dir/

                                12. 歸檔並保留元資料

                                如果要保留符號連結、時間戳、檔案許可權、檔案的使用者和組所有權,可以使用 -a 選項。

                                  rsync -a A/ Backup-A-dir/

                                  結合使用 -r 可以遞迴複製檔案並保留複製檔案的元資料。

                                  13. 設置檔案大小限制

                                  為了避免傳輸大檔案,可以使用 –max-size 選項設置檔案大小限制。

                                    rsync --max-size='100K' A/ Backup-A-dir/

                                    14. 設置頻寬限制

                                    –bwlimit 選項可以設置最大傳輸速率,單位是 kbps。

                                      rsync --bwlimit=100 A/ Backup-A-dir/

                                      15. 斷點續傳

                                      如果檔案傳輸不完整,可以使用 rsync 命令保留不完整的下載,以便在下一次發出相同命令時繼續傳輸。

                                      要恢復傳輸,使用 –append 選項:

                                        rsync --append A /Backup-A-dir/

                                        多執行緒傳輸

                                        以上都是一些基本的命令,是在單個進程中複製檔案。如果檔案特別大,比如有5TB,那麼整個傳輸過程的持續時間會非常長。這裡介紹一種方法可以加快傳輸速度,那就是使用parallel

                                        parallel 是用於執行併發作業的GNU程序,可以和 rsync 結合使用。

                                        與 rsync 一樣,parallel 也需要手動安裝:

                                          sudo apt install parallel

                                          在我們正式介紹 parallel 之前,先來了解一些它是如何工作的。我們來考慮一個類比:

                                          假設有1000個雞蛋和100個籃子,然後每個籃子配備一個無人機,任務就是將這1000個雞蛋交付給客戶。經理給每個籃子分配10個雞蛋,並將籃子交給無人機進行交付。這樣每個無人機都會執行一個操作(就是送籃子中的雞蛋,我們的例子中,就好比是 rsync 處理10個檔案)。經理監督無人機的工作。請注意,每個無人機都不知道是否還有其他無人機,只有經理才知道。

                                          類似地,rsync像無人機一樣執行檔案傳輸,而 parallel 就擔任經理的角色。

                                          parallel 將要傳輸的檔案分割成若干份(每份都是一個檔案列表),每份都由rsync啟動一個進程進行傳輸。rsync不知道其他並行的進程,也不具備並行傳輸的能力。而parallel就啟動rsync,來啟動並管理多個並行進程。

                                          因此,parallel 命令由兩部分組成,一個是參數(雞蛋/檔案),另一個是並行進程命令(管理器)。

                                            ls A/* | parallel -j 20 rsync A/{} /Backup-A-dir/

                                            在上述命令中,管道符號 | 左側的部分,輸出是一個檔案列表,每個檔案都作為一個參數;在 parallel 命令中,{} 則表示這些參數(相當於佔位符)。

                                            -j n,它給-n一個數字來表示任務數(或者進程數),本例中,n 是20;之後是 rsync 的常用命令,來處理每個參數(管道符號左側的檔案列表)。最後,它會被捆綁到20個進程中,並行執行。

                                            注意,上面的 rsync 命令就是普通的rsync命令,跟我們上面介紹的用法完全一樣,就像不用 parallel 時一樣,可以添加任何選項(比如 -z, -a, -e ssh等)。

                                            關於 garallel 的詳細介紹,可參考:

                                            https://www.gnu.org/software/parallel/

                                            使用 rsync 時的一些常見故障

                                            使用 rsync 時可能會遇到一些問題,下面是一些常見的錯誤。

                                            1. rsync 許可權被拒絕(rsync permission denied)

                                            當你使用沒有許可權的路徑時,就會報出這個錯,比如:

                                              rsync B/ /home/

                                              如果你沒有 /home 的寫入許可權,那上述命令就會報許可權被拒絕(普通使用者通常不這樣做)。

                                              2. 在中設置時間錯誤(rsync failed to set times on )

                                              當檔案系統無法處理檔案和目錄的修改時間時,就會發生這種情況。關於這個問題,可以參考:

                                              https://superuser.com/questions/200012/rsync-failed-to-set-times-on-dir-path

                                              以上就是本次分享全部內容,歡迎討論。

                                              相關文章

                                              吳峰光殺進 Linux 核心

                                              吳峰光殺進 Linux 核心

                                              【編者按】吳峰光,Linux 核心守護者,學生時代被同學戲稱為「老神仙」,兩耳不聞窗外事,一心只搞 Linux。吳峰光的 Linux 核心之...

                                              宮敏把自由軟體和 Linux 帶回中國

                                              宮敏把自由軟體和 Linux 帶回中國

                                              對於宮敏,在中國的開源界以及技術圈內,大家所熟知的是「中國 Linux 第一人」的稱呼,因為他用手提肩背的方式將 Linux 帶回了中國,組...