Skip to main content

如何使用 Rsync 同步本地和远程目录

作者 Jeanelle Horcasitas, Justin Ellingwood

导言

Rsync 代表 远程同步(remote sync),是一种远程和本地文件同步工具。它使用的算法只移动文件中已经改变的部分,从而尽量减少复制的数据量。 在本教程中,我们将给出 Rsync 的定义,回顾使用 rsync 的语法,讲解如何使用 Rsync 与远程系统同步,还会为你提供其他可使用的选项。

前期准备

要练习使用 rsync 在本地和远程系统之间同步文件,你将需要两台机器,分别作为本地和远程计算机。这两台机器可以是虚拟专用服务器、虚拟机、容器或个人电脑,只要它们先前经过了正确的配置。 如果你想使用两台服务器,可以将它们都设置为管理员,并在每台服务器上配置防火墙,这是更安全审慎的做法。 无论使用什么类型的机器来学习本教程,你都需要在这两台机器上创建 SSH 密钥,然后将每个服务器的公钥复制到另一个服务器的 authorized_keys 文件中。 本指南是在运行 Ubuntu 20.04 的机器上验证的,不过一般来说,本指南适用于任何运行基于 Linux 的操作系统并安装了 rsync 的计算机。

Rsync 的定义

Rsync 是一款十分灵活且支持网络的同步工具。Linux 和类 Unix 系统中经常能见到它的身影,此外,它作为系统脚本工具也很受欢迎,因此大多数 Linux 发行版中默认包含 Rsync。

了解 Rsync 同步

rsync 的语法与其他工具,比如 sshscpcp 类似。 首先,运行以下命令进入你的主目录:

cd ~

然后用以下代码创建一个测试目录:

mkdir dir1

创建另一个测试目录:

mkdir dir2

接下来添加一些测试文件:

touch dir1/file{1..100}

现在你已经创建好了目录 dir1,里面有100个空文件。可以列出这些文件以进行确认:

ls dir1

Output
file1 file18 file27 file36 file45 file54 file63 file72 file81 file90
file10 file19 file28 file37 file46 file55 file64 file73 file82 file91
file100 file2 file29 file38 file47 file56 file65 file74 file83 file92
file11 file20 file3 file39 file48 file57 file66 file75 file84 file93
file12 file21 file30 file4 file49 file58 file67 file76 file85 file94
file13 file22 file31 file40 file5 file59 file68 file77 file86 file95
file14 file23 file32 file41 file50 file6 file69 file78 file87 file96
file15 file24 file33 file42 file51 file60 file7 file79 file88 file97
file16 file25 file34 file43 file52 file61 file70 file8 file89 file98
file17 file26 file35 file44 file53 file62 file71 file80 file9 file99

同时还有一个名为 dir2 的空目录。 为了在同一系统上将 dir1 的内容同步到 dir2,你需要运行 rsync 并使用 -r 标记,它代表“递归(recursive)”,是目录同步时必须要进行的一步。

rsync -r dir1/ dir2

还有一个选择是使用 -a 标记,它是一个组合标记,代表“归档(archive)”。这个标记可以递归地同步,并保留符号链接、特殊文件、设备文件、修改时间、组、所有者和权限。它比 -r 更常用,也是推荐使用的标记。除了使用的是 -a 标记,这种选择运行的命令与前面的例子相同:

rsync -a dir1/ dir2

请注意,在前两条命令的语法中,第一个实参的末尾有一条斜杠(/)。 末尾的这条斜杠表示 dir1 的内容。如果末尾没有斜杠, dir1 的内容包括目录本身将被放在 dir2 中。 结果将是创建一个类似于下面的层次结构:

~/dir2/dir1/[files]

另一点要注意的是,在执行 rsync 命令前要仔细检查你的实参。Rsync 提供了一种方法,你可以通过传递 -n--dry-run 选项来做到这一点。要获得合适的输出,必须使用 -v 标记。在下面的命令中,你将结合使用 anv 标记。

rsync -anv dir1/ dir2

Output
sending incremental file list
./
file1
file10
file100
file11
file12
file13
file14
file15
file16
file17
file18
. . .

现在比较上面的输出与下面去掉尾部斜杠后的输出:

rsync -anv dir1 dir2

Output
sending incremental file list
dir1/
dir1/file1
dir1/file10
dir1/file100
dir1/file11
dir1/file12
dir1/file13
dir1/file14
dir1/file15
dir1/file16
dir1/file17
dir1/file18
. . .

这个输出表示传输的是目录本身,而不仅仅是目录中的文件。

使用 Rsync 与一个远程系统同步

要使用 rsync 与远程系统同步,你只需要在本地和远程机器之间配置 SSH 访问,以及在两个系统上安装 rsync 。验证过两台机器之间的 SSH 访问之后,你就可以使用以下语法将上一节中的 dir1 文件夹同步到远程机器上。请注意,在这种情况下,你要传输的是目录本身,所以要省略尾部的斜线。

rsync -a ~/dir1 username@remote_host:destination_directory

这个过程被称为 (push)操作,因为它把一个目录从本地系统“推”到了远程系统。与之相反的操作是“(pull)”,用于将一个远程目录同步到本地系统。如果 dir1 目录在远程系统上,需要同步到你的本地系统,语法将是:

rsync -a username@remote_host:/home/username/dir1 place_to_sync_on_local_machine

cp 和类似的工具一样,第一个实参总是源文件,而第二个实参总是目的地。

其他 Rsync 选项

Rsync提供了许多选项来改变自己的默认行为,例如你在上一节中了解到的标记选项。 如果你传输的文件(比如文本文件)还没有被压缩,可以使用 -z 选项进行压缩,以减少网络传输量:

rsync -az source destination

-P 标记也很有用。它结合了 --progress--partial 两个标记。第一个标记会为传输提供进度条,第二个标记允许你恢复中断的传输。

rsync -azP source destination

Output
sending incremental file list
created directory destination
source/
source/file1
0 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=99/101)
sourcefile10
0 100% 0.00kB/s 0:00:00 (xfr#2, to-chk=98/101)
source/file100
0 100% 0.00kB/s 0:00:00 (xfr#3, to-chk=97/101)
source/file11
0 100% 0.00kB/s 0:00:00 (xfr#4, to-chk=96/101)
source/file12
0 100% 0.00kB/s 0:00:00 (xfr#5, to-chk=95/101)
. . .

再次运行该命令,你会收到一个更短的输出,因为没有发生任何变化。这说明 Rsync 可以通过修改时间来确定是否进行了修改。

rsync -azP source destination

Output
sending incremental file list
sent 818 bytes received 12 bytes 1660.00 bytes/sec
total size is 0 speedup is 0.00

假设你用下面这样的命令来更新一些文件的修改时间:

touch dir1/file{1..10}

然后再次用 -azP 运行 rsync ,就能在输出中看到 Rsync 只会重新拷贝已更改的文件,这点十分智能:

rsync -azP source destination

Output
sending incremental file list
file1
0 100% 0.00kB/s 0:00:00 (xfer#1, to-check=99/101)
file10
0 100% 0.00kB/s 0:00:00 (xfer#2, to-check=98/101)
file2
0 100% 0.00kB/s 0:00:00 (xfer#3, to-check=87/101)
file3
0 100% 0.00kB/s 0:00:00 (xfer#4, to-check=76/101)
. . .

为了使两个目录真正保持同步,如果文件从源目录中被删除,目标目录也有必要删除这些文件。但默认情况下,rsync 不会从目标目录中删除任何东西。 可以用 --delete 选项来改变这一行为。在使用这个选项之前,你可以使用 -n,即 --dry-run 进行测试,以防止不必要的数据丢失。

rsync -an --delete source destination

如果你不想同步目录内的某些文件或目录,可以在 --exclude= 选项后面的列表指定它们,之间用逗号分隔。

rsync -a --exclude=pattern_to_exclude source destination

如果只想排除某一特定的模式,可以使用 --include= 选项来覆盖 --exclude=,确保符合某一不同模式的文件不会被排除:

rsync -a --exclude=pattern_to_exclude --include=pattern_to_include source destination

最后,Rsync 的 --backup 选项可以用来存储重要文件的备份。它与 --backup-dir 选项一起使用,后者指定了备份文件应该存储的目录:

rsync -a --delete --backup --backup-dir=/path/to/backups /path/to/source destination

结语

Rsync 可以简化网络文件传输,并增强本地目录同步的稳健性。它十分灵活,因而成为许多文件级操作的良好选择。 掌握 Rsync 之后,你就可以开始设计复杂的备份操作,并获得对传输方式和内容的细粒度控制。