跳转至内容

rsync

来自 ArchWiki

rsync 是一个提供快速增量文件传输的开源实用程序。

安装

安装 rsync 包。

rsync 必须安装在源机器和目标机器上。

前端

  • Grsync — GTK 前端。
https://www.opbyte.it/grsync/ || grsync
  • luckyBackup — 用 C++ 编写的 Qt 前端。
https://luckybackup.sourceforge.net/index.html || luckybackupAUR
  • nbRsync — 带有集成调度程序的 rsync 的 JavaFX GUI。
https://trixon.se/projects/nbrsync/ || 未打包? 在 AUR 中搜索

其他使用 rsync 的工具包括 rdiff-backupAURosyncAURyarsyncAUR

作为 cp/mv 的替代品

注意 使用 rsync 代替 cp/mv 在不同文件系统之间非常高效,但在同一文件系统内复制或移动文件则不然。请参见 [1]

rsync 可作为 cpmv 命令的高级替代品,尤其适用于复制大文件。

$ 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,progress2stats1 以详细级别 1 显示 rsync 传输统计信息。progress2 显示总传输进度,而不是每个文件的传输进度(progress1)。
  • --modify-window=1:在比较两个文件的修改时间戳时,如果它们的时间戳相差不到 1 秒,则认为它们的时间戳等效。
  • --remove-source-files:在文件成功同步后,从源目录中删除文件。
注意 术语 校验和 的使用 **不** 与 --checksum 选项的行为可互换。--checksum 选项会影响在任何文件传输之前使用的文件跳过启发式方法。与 --checksum 无关,校验和 始终用于基于块的文件构建,这是 rsync 传输文件的方式。

末尾斜杠的注意事项

Arch 默认使用 GNU cp(GNU coreutils 的一部分)。然而,rsync 遵循 BSD cp 的约定,该约定对末尾带有斜杠 "/" 的源目录给予特殊处理。而

$ rsync -r source destination

会创建一个名为 "destination/source" 的目录,其中包含 "source" 的内容,而命令

$ rsync -r source/ destination

会将 "source/" 中的所有文件直接复制到 "destination" 中,中间没有任何子目录——就像您调用它时一样

$ rsync -r source/. destination

此行为与 GNU cp 不同,GNU cp 将 "source" 和 "source/" 视为相同(但 "source/." 除外)。此外,一些 shell 在自动补全目录名称时会自动添加末尾的斜杠。由于这些因素,新用户或偶尔使用 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 配置文件中将其别名为 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:表示文件将被归档,这意味着它们的大多数特性都会被保留(但 **不** 包括 ACL、硬链接或扩展属性,如功能)。
  • --delete:表示源上的已删除文件也将在备份上被删除。

这里,/path/to/backup 应替换为需要备份的内容(例如,/home),而 /location/of/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(递归、链接、权限、时间、组、所有者、设备)。
注意 rsync 将尝试修改目标计算机上任何先前备份的文件,以匹配它们在源计算机上的当前状态,每次增量备份都是如此。这意味着在通过 SSH 备份由 root 拥有的文件时(并且当保留权限和所有权时,如使用 -a 选项),需要 root 访问目标计算机。自动化实现此目标的首选方法是设置 SSH 守护进程,允许 root 使用 无密码公钥 登录,并以 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 递归、链接、权限、时间、组、所有者、设备。
  • --files-from:从此文件读取 /path/to/backup 的相对路径。
  • --bwlimit:限制 I/O 带宽;每秒千字节数。

脚本必须由 root 拥有(有关详细信息,请参阅 NetworkManager#Network services with NetworkManager dispatcher)。

通过 systemd 和 inotify 进行自动化备份

  • 由于 inotify 和 systemd 的限制(请参阅 此问答),无法进行递归文件系统监控。虽然您可以监视一个目录及其内容,但它不会递归进入子目录并监视它们的内容;您必须显式指定要监视的每个目录,即使该目录是已监视目录的子目录。
  • 此设置基于 systemd/User 实例。

与运行基于时间的计划(如 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 文件。默认情况下,一个与路径单元同名的服务文件(在本例中为 backup.path)将被激活,但扩展名从 .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 并原地更新目标文件。

快照备份

相同的思路可用于维护文件快照树。换句话说,一个包含按日期排序文件副本的目录。副本使用硬链接创建,这意味着只有更改的文件才会占用空间。总的来说,这是 Apple Time Machine 背后的想法。

这个基本脚本易于实现,并使用 --link-dest 选项通过硬链接未更改的文件来创建快速的增量快照。

/usr/local/bin/snapbackup.sh
#!/bin/sh

# Basic snapshot-style rsync backup script 

# Config
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"`

# Run rsync to create snapshot
rsync $OPT $LINK $SRC ${SNAP}$date

# Remove symlink to previous snapshot
rm -f $LAST

# Create new symlink to latest snapshot for the next backup to hardlink
ln -s ${SNAP}$date $LAST

必须存在一个指向完整备份的符号链接作为 --link-dest 的目标。如果删除了最新的快照,则需要重新创建符号链接以指向最新的快照。如果 --link-dest 未找到有效的符号链接,rsync 将继续复制所有源文件,而不是只复制更改的文件。

更复杂的版本会维护一个最新的完整备份 $SNAP/latest,并且在自上次完整备份以来更改的文件数量达到一定程度时,它会创建一个当前完整备份的快照 $SNAP/$DATETAG,并利用 cp -al 来硬链接未更改的文件。

/usr/local/bin/rsnapshot.sh
#!/bin/sh

## my own rsync-based snapshot-style backup procedure
## (cc) marcio rps AT gmail.com

# config vars

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

# run this process with real low priority

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

# sync

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

# check if enough has changed and if so
# make a hardlinked copy named as the date

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/Timers 单元运行。

全系统备份

本节介绍如何使用 rsync 复制整个 / 树,并排除一些选定的目录。这种方法被认为优于使用 dd 进行 磁盘克隆,因为它允许使用不同大小、分区表和文件系统,并且也优于使用 cp -a 复制,因为它允许对文件权限、属性、访问控制列表扩展属性进行更精细地控制。

rsync 即使在系统运行时也能工作,但在传输过程中更改的文件可能会或可能不会被传输,这可能导致使用传输文件的某些程序出现未定义行为。为缓解此问题,请注销所有用户并关闭所有程序和数据库。

这种方法非常适合将现有安装迁移到新的硬盘驱动器或 SSD

以 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 选项集,文件以存档模式传输,从而确保符号链接、设备、权限、所有权、修改时间、ACL 和扩展属性得到保留,前提是目标 文件系统 支持该功能。-H 选项会保留硬链接,但会消耗更多内存。

--exclude 选项会导致与给定模式匹配的文件/目录被排除。或者,--exclude-from=file 选项会排除与 file 中的模式(每行一个)匹配的文件/目录,这类似于 #Advanced usage of filter rules 中描述的示例,但没有 +/- 语法。

上述命令中包含了 /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 的 --delete 选项。在这种情况下,请确保源路径不以 /* 结尾,否则该选项只会影响源目录子目录中的文件,而对直接位于源目录中的文件不起作用。
  • 如果您使用任何稀疏文件,例如虚拟磁盘、Docker 镜像等,则应添加 -S 选项。
  • --numeric-ids 选项将禁用用户和组名的映射;而是传输数字用户和组 ID。这在通过 SSH 进行备份或使用实时系统备份不同系统磁盘时非常有用。
  • 选择 --info=progress2 选项而不是 -v 将显示整体进度信息和传输速度,而不是正在传输的文件列表。
  • 为避免在递归时跨越文件系统边界,请添加 -x/--one-file-system 选项。这将阻止备份层次结构中的任何挂载点。

恢复备份

如果您想恢复备份,请使用与执行时相同的 rsync 命令,但源和目标颠倒(您可能还想在源后添加一个末尾斜杠)。如果您使用了 --exclude 选项,则在恢复命令中可能应该删除它们。

过滤规则的高级用法

rsync 可以从单个过滤文件中读取所有包含和排除规则,而不是分别指定它们。rsync 按自上而下的顺序处理规则;第一个匹配的规则生效。

backup.filter
# Exclude patterns

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

# Include patterns

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

# Exclude everything else
- /**

*** 是一个特殊的 rsync 模式,可以递归地匹配一个文件夹及其所有内容。

有关更多详细信息,请参见 rsync(1) § PATTERN MATCHING RULESrsync(1) § FILTER RULES IN DEPTH

然后使用以下命令运行 rsync:

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

关键是 --filter "merge ..." 参数,它将采用过滤文件并按顺序解析每个同步文件的规则。

从路径列表复制

--files-from 选项是 #Advanced usage of filter rules 方法的替代方案。它可以接受来自文本文件的输入,该文本文件包含目录或文件路径列表,每个条目由换行符分隔。需要注意的是,如果用户想要递归目录复制,即使已经包含了 -a,也必须手动为此选项指定 -r 标志。

例如,可以使用以下命令归档目录列表及其所有递归目录:

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

文件系统克隆

rsync 提供了一种复制文件系统所有数据的方法,同时尽可能保留信息,包括文件系统元数据。这是一个在文件系统级别进行数据克隆的过程,源文件系统和目标文件系统不必是同一类型。它可用于备份、文件系统迁移或数据恢复。

rsync 的*归档*模式接近于完成任务,但它不备份特殊文件系统元数据,如访问控制列表、扩展属性或稀疏文件属性。为了在文件系统级别成功克隆,需要提供一些额外的选项。

rsync -qaHAXS SOURCE_DIR DESTINATION_DIR

它们的含义(来自 manpage)是:

--hard-links, -H         preserve hard links
--acls, -A               preserve ACLs (implies --perms)
--xattrs, -X             preserve extended attributes
--sparse, -S             turn sequences of nulls into sparse blocks

此外,如果您有其他文件系统挂载在要从复制中排除的树下,请使用 -x

注意 如果您正在使用 rsync 将 Arch 安装迁移到新驱动器,请记住在 SOURCE_DIR 的末尾包含一个斜杠,原因如 #Trailing slash caveat 中所述。

生成的副本可以简单地在文件系统级别使用 diff 的递归选项进行重新读取和检查(例如,在数据恢复尝试后)。

diff -r SOURCE_DIR DESTINATION_DIR

可以通过使用本文档所述的 rsync 来成功进行文件系统迁移,并更新 fstab引导加载程序,如 Migrate installation to new hardware 中所述。这基本上提供了一种将任何根文件系统转换为另一种的方法。

作为守护进程

rsync 可以作为一个 守护进程 在服务器上运行,监听 TCP 端口 873

编辑模板 /etc/rsyncd.conf,配置一个共享,然后 启动 rsyncd.service

注意rsync 3.2.0-1 开始,该软件包采用了上游 systemd 单元文件 rsyncd.servicersyncd@.serviceProtectHome 的更改已被注释掉,但 [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
...

# Needed when crossing filesystem boundaries.
#use chroot  = no
read only = yes

...

[sync]
    path         = /
# List of files to copy.
    include from = /backup.list
# Exclude the rest.
    exclude      = *

在文件列表中,所有*中间路径*都是必需的,除非使用了 *** 通配符。

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

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.