rsync - Arch Linux 中文维基

跳至內容

# rsync

出自 Arch Linux 中文维基

相關文章

- 系統備份
- 同步和備份程序

翻譯狀態：

- 本文（或部分內容）譯自 rsync，最近一次同步於 2024-05-21，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

rsync 是一個開源工具，可以進行快速的增量文件傳輸。

## 安裝

安裝 rsync包 軟體包。

必須在源計算機和目標計算機上都安裝 rsync。

### 前端

- Grsync — GTK 前端。

  https://www.opbyte.it/grsync/ || grsync包

- JotaSync — 用於 rsync 的 Java Swing GUI，內置計劃功能。

  https://trixon.se/projects/jotasync/ || jotasyncAUR

- luckyBackup — 用 C++ 編寫的 Qt 前端。

  https://luckybackup.sourceforge.net/index.html || luckybackupAUR

其他使用 rsync 的工具是 rdiff-backupAUR, osyncAUR 和 yarsyncAUR。

## 作為 cp/mv 的替代

注意：在不同的文件系統之間使用 rsync 而不是 cp/mv 是高效的，但對於在同一個文件系統上複製或移動文件卻不然。參見 [1]

rsync 可以作為 `cp` 或 `mv` 命令的高級替代品，特別是對於較大文件的複製：

    $ rsync -P source destination

其中 `-P` 與 `--partial --progress` 選項的作用是相同的，該選項使得文件可以分塊傳輸並顯示傳輸過程中的進度。

您可能需要使用 `-r`/`--recursive` 選項遞歸到目錄中傳輸。

可以像 cp 命令一樣本地複製文件，但 rsync 令人激動的用途在於遠程複製文件，例如在兩個不同的主機之間。遠程位置可以用主機加冒號進行指定：

    $ rsync source host:destination

或者

    $ rsync host:source destination

網絡文件傳輸默認使用SSH協議，`host` 可以是真實的主機名或來自於 `.ssh/config` 的預先定義的配置文件/別名。

無論是本地或遠程文件傳輸，rsync 首先會創建一個文件列表，其中含有接下來會被用於確定各個文件是否需要構建的信息（默認為文件大小和上次修改時間戳）。對於每個需要構建的文件，都會找出其所有塊（長度S字節，不重疊，偏移量可由S整除）的一個弱校驗和和一個強校驗和。使用這一信息，一個大文件就可以由 rsync 構建，而無需傳輸整個文件。更詳細的實際解釋和詳細的數學解釋見 rsync 如何工作及 rsync 算法。

要快速使用合理默認值，可以使用一些別名：

    cpr() {
      rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 "$@"
    }
    mvr() {
      rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 --remove-source-files "$@"
    }

- `-hh`: 以人類可讀的格式輸出數字
- `--info=stats1,progress2`: `stats1` 使用詳細級別1顯示 rsync 傳輸統計信息。`progress2` 列印總的傳輸進度，而不是每個文件的傳輸進度(`progress1`)
- `--modify-window=1`: 當比較兩個文件的時間戳時，如果時間戳的差異小於1秒，則將它們的時間戳視為相等
- `--remove-source-files`: 成功同步後從源目錄中刪除文件

注意：此處對校驗和這一名詞的使用與 `--checksum` 選項的行為不是相等價的。`--checksum` 選項影響的是在傳輸任何文件之前使用的決定是否跳過文件的啟發式方法。在基於塊的文件構建中一定會使用校驗和，這是 rsync 傳輸文件的方法，與 `--checksum` 無關。

### 注意尾部的斜槓

Arch 默認使用 GNU cp (coreutils包 的一部分)。 然而，rsync 遵循 BSD cp 的約定, 源目錄後面帶有一個斜槓「/」有著特殊的處理。比如命令

    $ rsync -r source destination

創建一個包含"source"的內容的"destination/source"目錄。而命令

    $ rsync -r source/ destination

把"source/"目錄下的所有文件全部複製到"destination"目錄下，而沒有中間的子目錄，和以下命令一樣：

    $ rsync -r source/. destination

這與 GNU cp 的行為是不同的，在 GNU cp 中"source" 與 "source/" 意義相同 ("source/."則不然)。並且，一些shell在Tab補全目錄名的時候自動追加尾部下劃線。由於這些因素，新手或偶爾使用 rsync 的用戶可能傾向於忘記 rsync 的不同行為，在命令行上留下了尾部斜槓，從而無意間弄錯，甚至覆蓋重要文件。

謹慎起見，可以使用包裝腳本在調用 rsync 之前自動刪除尾部斜槓：

    #!/bin/bash
    new_args=()
    for i in "${@}"; do
        case "${i}" in
            /)
                i="/"
            ;;
            */)
                i="${i%/}"
            ;;
            esac
        new_args+=("${i}")
    done
    exec rsync "${new_args[@]}"

該腳本可以放在 path 中的某個位置，並在 shell 的 init 文件中指定別名為 rsync。

## 作為備份工具

rsync 協議可以很容易地用於備份，只傳輸自上次備份以來已更改的文件。本節將介紹一些簡單的基於 rsync 的計劃備份腳本，通常用於複製到可移動介質。

### 自動備份

以下面的腳本為例，該腳本放置於 `/etc/cron.daily` 目錄下，如果 cron 守護程序被正確安裝和配置，它將每天運行。配置和使用 cron 是本文的範圍之外。

首先，創建一個包含相應命令選項的腳本：

    /etc/cron.daily/backup

    #!/bin/sh
    rsync -a --delete --quiet /path/to/backup /location/of/backup

`-a`
  表示文件應被存檔，這意味著他們的大部分特性被保留 (不包括 ACLs, 硬連結或擴展屬性，如 capabilities)
`--delete`
  指同步源的刪除操作。

在這裡，`/path/to/backup` 應該改成需要被備份的路徑 (比如 `/home`)，`/location/to/backup` 是備份應存放的位置 (比如 `/media/disk`).

最後，腳本必須可執行。

### 通過 SSH 自動備份

如果是通過 SSH 備份到遠程主機，改為使用此腳本：

    /etc/cron.daily/backup

    #!/bin/sh
    rsync -a --delete --quiet -e ssh /path/to/backup remoteuser@remotehost:/location/of/backup

`-e ssh`
  告訴rsync的使用SSH
`remoteuser`
  遠程主機 `remotehost` 上的用戶名
`-a`
  組中的所有這些選項 `-rlptgoD` (recursive, links, perms, times, group, owner, devices)

注意： 在每次增量備份的時候，Rsync 都會試著修改目標主機上所有先前備份過的文件以匹配源主機上的文件狀態。這意味著在通過 SSH （並且使用 `-a`選項保留權限和所有者的時候）備份屬於 root 的文件，需要目標主機的 root 權限。通常的辦法是將 SSH 守護程序設置為允許使用公鑰而不是密碼登錄，並以 root 用戶運行 rsync 命令。

### 使用 NetworkManager 自動備份

該腳本在網絡連接後開始備份。

首先，創建一個包含相應命令選項的腳本：

    /etc/NetworkManager/dispatcher.d/backup

    #!/bin/sh

    if [ x"$2" = "xup" ] ; then
            rsync --force --ignore-errors -a --delete --bwlimit=2000 --files-from=files.rsync /path/to/backup /location/of/backup
    fi

`-a`
  組中的所有選項 `-rlptgoD` recursive, links, perms, times, group, owner, devices
`--files-from`
  從文件中讀取到備份路徑`/path/to/backup`的相對路徑
`--bwlimit`
  限 I/O 帶寬；每秒千字節

這個腳本必須屬於 root 用戶 (參見 NetworkManager#使用 NetworkManager 調度網絡服務 )。

### 使用 systemd 和 inotify 自動備份

注意：

- 由於 inotify 和 systemd 的限制， (見 這個問題和回答)，遞歸的文件系統監測是不可能的。即使你監測了一個目錄和它的內容，它也不會遞歸子目錄並檢測其中的內容。你必須明確地指出所有需要檢測的目錄，就算這些目錄是你已經監視的目錄的子目錄。
- 以下設置基於一個 systemd/用戶 的實例。

相比於執行一個基於時間計劃的定時備份，比如使用 cron，在每次文件變動的時候都執行備份也是可行的。`systemd.path` 單元使用 `inotify` 以監測文件系統，並且可以與 `systemd.service` 文件一同使用來在捕獲到文件系統事件的時候啟動任何進程（如你的 rsync 備份）。

首先，創建監測備份文件的 `systemd.path` 文件：

    ~/.config/systemd/user/backup.path

    [Unit]
    Description=Checks if paths that are currently being backed up have changed

    [Path]
    PathChanged=%h/documents
    PathChanged=%h/music

    [Install]
    WantedBy=default.target

然後創建一個 `systemd.service` 文件，它將會在檢測到變化的時候啟動。默認情況下一個與 `.path` 單元同名(本例中為 `backup.path`)，但以 `.service` 結尾的服務（本例中為 `backup.service`）將會啟動。

注意：如果你需要運行多個 rsync 命令，使用 `Type=oneshot`。這將允許你指定多個 `ExecStart=` 參數，每個參數對應一個 rsync 命令。更簡單的方法是寫一個腳本來啟動你所有的備份，就像 cron 腳本一樣。

    ~/.config/systemd/user/backup.service

    [Unit]
    Description=Backs up files

    [Service]
    ExecStart=/usr/bin/rsync %h/./documents %h/./music -CERrltm --delete ubuntu:

現在只需要像普通的 systemd 服務那樣，啟動/啟用 `backup.path` 它就會開始監測文件變化並且自動啟動 `backup.service` 了。

### 每周差異備份

這個 rsync 選項很有用，每次運行時創建一個完整備份，並且每天在一個單獨的目錄中保留已修改文件的差異備份副本。

首先，創建一個包含相應命令選項的腳本：

    /etc/cron.daily/backup

    #!/bin/sh

    DAY=$(date +%A)

    if [ -e /location/to/backup/incr/$DAY ] ; then
      rm -fr /location/to/backup/incr/$DAY
    fi

    rsync -a --delete --quiet --inplace --backup --backup-dir=/location/to/backup/incr/$DAY /path/to/backup/ /location/to/backup/full/

`--inplace` 選項包含 `--partial` ，就地更新目標文件。

### 快照備份

同樣你也可以用這個工具來創建你文件的快照樹（即一個有日期順序的文件副本的目錄）。這個快照樹是基於硬連結的，這意味著只有修改過的文件才會占用空間。這也是蘋果 TimeMachine 的原理。

實現這個功能的腳本很容易實現，使用 `--link-dest` 選項來創建增量快照，硬連結未改變的文件：

    /usr/local/bin/snapbackup.sh

    #!/bin/sh

    # 基本的快照式 rsync 备份脚本

    # 配置
    OPT="-aPh"
    LINK="--link-dest=/snapshots/username/last/"
    SRC="/home/username/files/"
    SNAP="/snapshots/username/"
    LAST="/snapshots/username/last"
    date=`date "+%Y-%b-%d:_%T"`

    # 运行 rsync 以创建快照
    rsync $OPT $LINK $SRC ${SNAP}$date

    # 删除指向上一个快照的符号链接
    rm -f $LAST

    # 创建到最新快照的新符号链接，以便下次备份到硬链接
    ln -s ${SNAP}$date $LAST

這裡必須有一個指向完整備份的符號連結，以作為 `--link-dest` 的目標。如果最近的快照被刪除，那麼就需要重新創建一個指向新的快照的符號連結。如果 `--link-dest` 沒有找到有效的符號連結，rsync將繼續複製所有文件，而不只複製變化。

一個更加複雜一點的版本每次保留一個最新的完整備份到 `$SNAP/latest` 。若自上次完整備份起有一定數量的文件發生了變化，那麼腳本將創建一個新的快照到 `$SNAP/$DATETAG` ，並使用 `cp -al` 來硬連結未改變的文件：

    /usr/local/bin/rsnapshot.sh

    #!/bin/sh

    ## 我自己的基于 rsync 的快照式备份过程
    ## (cc) marcio rps AT gmail.com

    # 配置变量

    SRC="/home/username/files/" #dont forget trailing slash!
    SNAP="/snapshots/username"
    OPTS="-rltgoi --delay-updates --delete --chmod=a-w"
    MINCHANGES=20

    # 以低优先级运行此进程

    ionice -c 3 -p $$
    renice +12  -p $$

    # 同步

    rsync $OPTS $SRC $SNAP/latest >> $SNAP/rsync.log

    # 检查是否有足够的变化，如果有
    # 则制作一份以日期命名的硬链接副本

    COUNT=$( wc -l $SNAP/rsync.log|cut -d" " -f1 )
    if [ $COUNT -gt $MINCHANGES ] ; then
            DATETAG=$(date +%Y-%m-%d)
            if [ ! -e $SNAP/$DATETAG ] ; then
                    cp -al $SNAP/latest $SNAP/$DATETAG
                    chmod u+w $SNAP/$DATETAG
                    mv $SNAP/rsync.log $SNAP/$DATETAG
                   chmod u-w $SNAP/$DATETAG
             fi
    fi

懶得手動運行的話，你也可以讓這個腳本作為 systemd/定時器單元運行。

### 全盤系統備份

本節介紹使用rsync傳輸整個/樹的副本，不包括一些選定的目錄。這種方法被認為比使用dd進行磁碟克隆更好，因為它允許使用不同的大小、分區表和文件系統，也比使用cp-a進行複製更好，因為其允許對文件權限、屬性、訪問控制列表和擴展屬性進行更大的控制。 本節是關於使用 rsync 來創建一份整個 `/` 樹的副本，其中不包含特定的幾個文件夾。此方法相較於使用 `dd` 來進行硬碟克隆要更佳，因為它允許你在使用不同大小、分區表和文件系統的存儲設備間傳輸；也比 `cp -a` 更好，因為它允許你對文件權限、屬性、訪問控制列表和擴展屬性有更好的掌握。

rsync 在系統運行時亦可進行備份，但傳輸期間改變的文件可能不會被備份。這可能會造成使用這些文件的程序的一些未知錯誤或未定義行為。為緩解這個問題，可以註銷所有用戶並關閉所有程序和資料庫。

這種方法對於將現有的已安裝系統遷移到新的硬碟或固態硬碟上非常有效。

在 root 權限下運行此命令，以確保 rsync 能訪問到所有系統文件，並且保留權限：

     # rsync -aAXHv --exclude='/dev/*' --exclude='/proc/*' --exclude='/sys/*' --exclude='/tmp/*' --exclude='/run/*' --exclude='/mnt/*' --exclude='/media/*' --exclude='/lost+found/' / /path/to/backup

通過使用 `-aAX` 選項集，文件以歸檔模式傳輸，確保符號連結、設備、權限、所有權、修改時間、ACLs和擴展屬性得以保留，前提是目標文件系統支持這一功能。選項 `-H` 保留了硬連結，但會使用更多的內存。

`--exclude` 選項使符合給定模式的文件/文件夾被排除。可以結合使用`--exclude-from=file`選項，排除與`file`中的模式（每條一個）相匹配的文件/目錄。這與#篩選規則的高級用法中描述的例子類似，但不需要`+`/`-`語法。

在上述命令中，`/dev`、`/proc`、`/sys`、`/tmp`和`/run` 等目錄被包括在內，但這些目錄的內容被排除在外。這是因為它們在系統啟動時才會被填入內容，但這些目錄本身不會被創建。 `/lost+found` 是針對文件系統的。為排除模式加上引號可以避免被 shell 誤擴展，例如，在通過 SSH 備份時，這是必要的。以 `*` 結尾的排除路徑可以確保目錄本身在不存在的情況下被創建。

注意：

- 如果計劃將系統備份到 `/mnt` 或 `/media` 以外的其他位置，請不要忘記將其添加到排除的模式列表中，以避免無限循環。
- 如果系統中有任何綁定掛載，也應排除它們，以便綁定掛載的內容只複製一次。
- 如果使用交換文件，請確保也將其排除在外。
- 考慮是否要備份 `/home/` 目錄。如果它包含您的數據，它可能比系統大得多。另外，請考慮排除不重要的子目錄，例如 `/home/*/.thumbnails/*`, `/home/*/.cache/mozilla/*`, `/home/*/.cache/chromium/*`, 和 `/home/*/.local/share/Trash/*`，具體取決於系統上安裝的軟體。
- 如果安裝了 GVFS，則必須排除 `/home/*/.gvfs`，以防止 rsync 錯誤。
- 如果安裝了 Dhcpcd ≥ 9.0.0，請排除 `/var/lib/dhcpcd/*` 目錄，因為它將多個系統目錄作為子目錄掛載在那裡。

您可能希望包括其他 rsync 選項，或刪除一些選項，例如以下選項。有關完整列表，請見 rsync(1)。

- 如果您在內存非常低的系統上運行，請考慮刪除 `-H` 選項；然而，這在大多數現代機器上應該沒有問題。文件系統上可能有許多硬連結，具體取決於使用的軟體（例如，如果您使用 Flatpak）。許多硬連結位於 `/usr/` 目錄下。
- 如果在同一備份目錄中多次運行 rsync，則可能需要添加 rsync 的 `--delete` 選項。在這種情況下，請確保源路徑不以 `/*` 結尾，否則此選項將僅對源目錄子目錄中的文件有效，但對直接駐留在源目錄內的文件無效。
- 如果您使用任何稀疏文件，如虛擬磁碟、Docker 映像和類似文件，則應添加 `-S` 選項。
- `--numeric-ids` 選項將禁止映射到用戶名和組名；相反，數字的組和用戶 ID 將被直接傳輸。這在通過 SSH 進行備份或使用 live 系統備份不同的系統盤時非常有用。
- 選擇 `--info=progress2` 選項而不是 `-v` 選項將顯示整體進度信息和傳輸速度，而不是正在傳輸的文件列表。
- 為了避免在遞歸時跨越文件系統邊界，請添加選項 `-x`/`--one-file-system`。這將防止備份層次結構中的任何掛載點。

### 還原備份

如果希望還原備份，請使用執行的 rsync 命令，但源和目標相反。

### 篩選規則的高級用法

rsync 可以從單個過濾器文件中讀取所有這些規則，而不是單獨指定包含和排除規則。rsync 以自頂向下的順序處理規則；首先匹配的規則獲勝。

    backup.filter

    # 排除的模式

    - .thumbnails/***
    - node_modules/***
    - venv/***

    # 包含的模式

    + /Documents/***
    + /Books/***
    + /Music/***

    # 排除其他所有內容
    - /**

`***` 是一種特殊的 rsync 模式，它遞歸地匹配文件夾及其所有內容。

查看 rsync(1) § PATTERN MATCHING RULES 和 rsync(1) § FILTER RULES IN DEPTH 獲取更多詳情。

然後用此命令運行 rsync：

    $ rsync -aAXHv --filter="merge backup.filter" $SRC $DEST

關鍵字是 `--filter "merge ..."` 參數，它將獲取過濾器文件並按順序解析每個同步文件的規則。

### 從路徑列表複製

除了使用#篩選規則的高級用法外，還可以使用`--files-from` 選項。它可以從包含目錄或文件路徑列表的文本文件中獲取輸入，每條路徑都以新行分隔。需要注意的是，如果用戶想要遞歸複製目錄，即使已經包含 `-a` 選項，也必須手動為該選項指定 `-r` 標誌。

例如，可以使用以下命令歸檔目錄列表和所有遞歸目錄：

    $ rsync -aAXHvr --files-from="dir_list.txt" $SRC $DEST

## 文件系統克隆

rsync 提供了一種複製文件系統中所有數據的方法，同時保留儘可能多的信息，包括文件系統元數據。這是一個文件系統級別的數據克隆過程，其中源文件系統和目標文件系統不需要是同一類型。它可以用於備份、文件系統遷移或數據恢復。

rsync 的歸檔模式接近於適合該工作，但它不備份特殊的文件系統元數據，例如訪問控制列表、擴展屬性或稀疏文件財產。為了在文件系統級別成功克隆，需要提供一些其他選項：

    rsync -qaHAXS SOURCE_DIR DESTINATION_DIR

它們的意思是（來自手冊頁）：

    --hard-links, -H        保留硬链接
    --acls, -A              保留 ACLs（包含 --perms）
    --xattrs, -X            保留扩展属性
    --sparse, -S            将空序列转换为稀疏块

此外，如果要從副本中排除樹下掛載的其他文件系統，請使用 `-x`。

注意：如果您正在使用 rsync 將 Arch 安裝遷移到新驅動器，請記住在 `SOURCE_DIR` 末尾添加一個尾隨斜槓，原因在#注意尾隨下劃中提到。

可以使用 `diff` 的遞歸選項在文件系統級別簡單地重新讀取和檢查生成的副本（例如，在數據恢復嘗試之後）：

    diff -r SOURCE_DIR DESTINATION_DIR

通過使用 rsync（如本文所述）和更新 fstab 和引導加載程序（如遷移到新硬體中所述），可以成功執行文件系統遷移。這本質上提供了一種將任何根文件系統轉換為另一個文件系統的方法。

## 作為守護程序

rsync 可以在偵聽TCP埠 `873` 的伺服器上作為守護程序運行。

編輯模板 `/etc/rsyncd.conf`，配置共享並啟動 `rsyncd.service`。

注意：截至 rsync包 3.2.0-1，該軟體包採用了上游 systemd 單元文件 `rsyncd.service` 和 `rsyncd@.service`。`ProtectHome` 的更改已被注釋，`[Service]` 節下的安全功能 `ProtectSystem=full` 仍處於活動狀態。這將使 `/boot/`, `/etc/` 和 `/usr/` 目錄只讀。如果您需要 rsyncd 寫入系統目錄，您可以編輯該單元，並在重寫代碼段的 `[Service]` 節中設置 `ProtectSystem=off`。

來自客戶端使用，例如列出伺服器內容：

    $ rsync rsync://server/share

將文件從客戶端傳輸到伺服器：

    $ rsync local-file rsync://server/share/

考慮在防火牆中打開 TCP 埠 `873`，並使用用戶身份驗證。

注意：包括用戶身份驗證在內的所有傳輸數據均未加密。

### 示例配置

#### 從文件列表共享

    /etc/rsyncd.conf

    ...

    # 跨越文件系統邊界時需要。
    #use chroot  = no
    read only = yes

    ...

    [sync]
        path         = /
    # 要複製的文件列表。
        include from = /backup.list
    # 排除其餘部分。
        exclude      = *

在文件列表中，所有中間路徑都是必需的，除非使用 `***` 通配符：

    /backup.list

    /etc/
    /etc/conf.d/
    /etc/conf.d/hwclock
    /etc/fonts/***

## 另見

- 更多用法示例在社區貢獻和 General Programming 論壇
- 如何 – 使用帶硬連結的 rsync 進行本地和遠程快照備份包括帶硬連結的文件重複數據消除、MD5 完整性簽名、'chattr' 保護、過濾規則、磁碟配額、指數分布的保留策略（備份循環，同時保存比舊備份更新的備份）
- 與 SSH 密鑰/身份文件一同使用 rsync

分類：​

- 同步
- 備份
- 命令

rsync
新增話題