李守中

rsync v3.2.7 man(1) page 中文译本

Table of Contents

1. 译者总注

1.1. 关于此译本

李守中是开源软件理念坚定的支持者,所以译本虽不是软件,但依旧仿照开源软件的协议发布:

  • 无担保:本文作者不保证作品内容准确无误,亦不承担任何由于使用此文档所导致的损失。
  • 自由使用:任何人都可以自由地 阅读/链接/打印 此文档,无需任何附加条件。
  • 名誉权:任何人都可以自由地 转载/引用/再创作 此文档,但必须保留作者署名并注明出处。

如果读者发现作品中有错误的地方,劳请来信指出。任何提高作品质量的建议李守中都将虚心接纳。

1.2. 原文档来源

本文档根据 rsync v3.2.7 manpage (man 1 rsync) 翻译。

1.3. 译者的话

对于直译后无法准确描述软件行为的句子,李守中会根据软件行为对这些句子进行意译。

对于必须添加很多内容才能实现意译的句子,李守中会尽量用直译 + 译者注 的方式来翻译。

受限于李守中的中文水平,在对句子进行意译时可能会偏离作者的本意,请读者谨慎参考。

有能力的读者可以从此链接 rsync v3.2.7 man(1) page 下载英文原文与本文做对照。

由于软件历史太长,文档的不同章节质量不一,很多地方的遣词造句很难理解。对于这些部分,能通过观察软件行为来理解的,李守中自己重写了这些部分;对于无法通过观察软件行为来理解的,李守中尽量意译了这些部分,并提示读者。另外,本译文会不加提示地大量使用意译,错误的地方可能比较多,推荐在阅读本文档时与原文一起读。


2. 名称

rsync - 快速、多用途的远程 (与本地) 文件拷贝工具。

3. 语法

  • 本地:
    • rsync [OPTION...] SRC... [DEST]
  • 通过 remote shell 访问:
    • 从远端拉取:
      • rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    • 推送到远端:
      • rsync [OPTION...] SRC... [USER@]HOST:DEST
  • 通过 rsync daemon 访问:
    • 从远端拉取:
      • rsync [OPTION...] [USER@]HOST::SRC... [DEST]
      • rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    • 推送到远端:
      • rsync [OPTION...] SRC... [USER@]HOST::DEST
      • rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

在命令中只写 SRC 参数而不写 DEST 参数可以列出 SRC 下的所有源文件,而不复制任何东西。

此手册页的英文在线版本(包括主题的交叉链接)可从以下网址获得:https://download.samba.org/pub/rsync/rsync.1

4. 描述

Rsync 是一个快速、多用途的文件拷贝工具。它可以在本地拷贝文件,也可以通过任何 remote shell 或者其他主机上的 rsync daemon 向其他主机推送或从其他主机拉取文件。它提供了大量的配置项来控制它行为的每一个方面,可以灵活地指定要复制的文件集。它以 delta-transfer 算法闻名,这个算法通过只发送源文件与已存在的目标文件不同的部分,减小了通过网络传递的文件数据的数量。Rsync 被广泛用于数据备份、数据镜像,也在日常中作为 cp 的指令的替代指令使用。

Rsync 在默认情况下使用 quick check 算法查找需要被传输的文件。quick check 算法通过文件大小、最后修改日期的改变来判断文件是否发生改变。当 quick check 判断不需要更新文件的数据时,将直接在目标文件上更改其他保留属性 (根据配置项的要求)。

Rsync 的其他特性:

  • 支持复制链接、设备,文件属主,文件属组与权限
  • exclude 与 exclude-from 选项与 GNU tar 命令类似
  • CVS 排除模式 (CVS exclude mode) 用于排除被 CVS 忽略的文件
  • 可以使用任何的 remote shell,包括 ssh 或者 rsh
  • 不需要管理员权限
  • 以流 pipelining 进行文件传输,最大限度地减少延迟
  • 支持匿名或经过身份验证的 rsync daemon (非常适合制作数据镜像)

5. 总览

Rsync 可将文件复制到远程主机,或从远程主机复制文件,或在当前主机上本地复制文件 (它不支持在两个远程主机之间复制文件)。

有两个不同的方式来访问远程主机系统: 使用 remote shell 程序作为传输方式 (比如 ssh 或者 rsh),或者直接用 TCP 直接连接到 rsync daemon。只要 SRC 或 DEST 路径在主机名后包含单个冒号分隔符 (:),就会使用 remote shell 传输。如果 SRC 路径或 DEST 路径在主机名后跟两个冒号分隔符 (::),或者指定了 rsync://<URL> 则直接连到 rsync daemon。(另参阅 "通过 remote shell 连接使用 rsync daemon 功能",了解后一条规则的例外情况)

一个特例,如果只有一个 SRC 参数而没有 DEST 参数,会产生类似于 ls -l 的输出。

如预期的那样,如果 SRC 路径或 DEST 路径都未指定远程主机,则复制将在本地进行 (另请参见 --list-only 选项)。

Rsync 将本地侧称为 client,将远程侧称为 server。不要搞混 rsync server 和 rsync daemon。一个 daemon 总是一个 server,但 server 可以是 daemon,也可以是 remote shell 派生的进程。

6. 安装

从 README.md 查看安装指导。

一旦安装,你可以使用 rsync 通过远程 shell 连接到任何你拥有访问权限的机器 (还可以连接到你拥有 rsync daemon-mode protocol 访问权限的机器)。对于远程传输,现代 rsync 使用 ssh 通信,但它可能已经被配置为默认使用不同的 shell,比如 rsh 或者 remsh。

你也可以指定任何你喜欢的远程 shell,使用 -e 命令行选项指定,或者修改 RSYNC_RSH 环境变量的值指定 shell。

注意,rsync 必须在本地机器与远程机器上同时安装。

7. 使用

rsync 与 rcp 的使用方式相同。你必须指定 SRC 与 DEST,其中一个可能是远程主机。

或许最好的解释语法的方式是给一些例子:

rsync -t *.c foo:src/

译者注: DEST 的路径字符串部分使用了相对路径,这个相对路径的根是用户登录之后的家目录。

上面的命令将传输当前文件夹下所有与模式 *.c 匹配的文件到目标机器 foo 的 src 目录下。如果被传输的文件已经存在于 DEST 上,rsync remote-update protocol 将会只更新文件有变动的部分的数据。注意,命令行中的通配符 (*.c) 被翻译成文件列表这个行为是在 rsync 运行前由 shell 而不是 rsync 完成的 (与所有其他 Posix 风格的程序完全相同)。

rsync -avz foo:src/bar /data/tmp

上面的命令将递归地传输远程机器 foo 上的 src/bar 目录到本地机器的 /data/tmp/bar 目录下。文件会被以存档模式传输,它保证了所有的符号链接、设备、属性、权限、所有权等都被传输。除此之外,这样传输也可以压缩被传输的数据的大小。

rsync -avz foo:src/bar/ /data/tmp

在 SRC 之后的斜杠让程序在复制过程之中不在 DEST 路径下创建顶层目录。可以考虑在 SRC 路径尾部加上 / 表示 "拷贝文件夹中的内容" 而不是 "根据名字拷贝文件夹",但在两个情况中包含目录的属性将传输到目标上的包含目录。换句话说,下面的每个命令都用同样的方式拷贝文件,包括 /dest/foo 的设定和属性:

译者注: 上面的命令会把 foo:src/bar 这个文件夹的属性原封不动地搬到 /data/tmp 上。而 foo:src/bar 则会在 data/tmp 下创建与 foo:src/bar 具有相同属性的文件夹。下面两个命令的结果都是在 /dest 下创建一个和 /src/foo 具有相同设定和属性的文件夹。

rsync -av /src/foo  /dest
rsync -av /src/foo/ /dest/foo

还要注意,主机根目录和模块引用不需要在尾部添加斜杠来复制默认目录的内容。比如,下面两条命令都会拷贝远程机器系统上文件夹的默认内容到 /dest 下:

rsync -av host:         /dest
rsync -av host::module  /dest

译者注: 第一条命令的效果是,拷贝 host 主机的 / 目录到本地的 /dest 目录下。第二条命令的效果是拷贝 rsync 模块指定的内容到本地的 /dest 目录下。

你也可以仅在本地使用 rsync,此模式下 SRC 和 DEST 在字段中都不包含 ':'。在这种情况下它像是被改进过的 cp 命令。

最后,你可以通过省略模块名称,从特定的 rsync daemon 列出所有可以列出的 rsync 模块:

rsync somehost.mydomain.com::

8. 拷贝后使用不同的名字

如果要拷贝 SRC 目录,并让 DEST 目录使用不同的名字。在 SRC 路径的尾部加一个斜杠可以让 rsync 拷贝 SRC 目录的内容到任何 DEST 目录下:

rsync -ai foo/ bar/

译者注: 就是上一节提到的路径尾部加不加斜杠的问题。加斜杠拷贝目录的内容,不加斜杠先创建同名目录再拷贝。

rsync 也可以在拷贝单个文件时修改目标文件的名称。规则是:

  • 传输列表必须由单个项目组成 (可以是一个文件或一个空目录) 译者注: 就是要传输的对象必须是一个文件或者一个空目录
  • 目标路径不能是一个目录
  • 目标路径不能以斜杠结尾

在这种情况下,rsync 会将目标对象的名称设置为目标路径的最后一个元素。 译者注: 目标路径 save/bar.c 中最后一个元素是 bar.c。 请记住,最好只在复制文件时使用该方法,而在复制目录时使用上面带斜杠的方法。

下面的例子拷贝了 foo.c 文件作为 save 目录下的 bar.c 文件 (假设 bar.c 不是目录):

rsync -ai src/foo.c save/bar.c

如果在复制多个文件时使用了复制单个文件并修改文件名的语法,比如:

rsync -ai src/*.c save/dir

如果在复制一个项目时指定了一个不存在的目标目录 (目标路径后面不加斜杠),比如 src/*.c 可以匹配一个文件,而 save/dir 目录不存在,程序的行为是复制这一个文件到目标路径的一级父路径下并改名为原本指定的目录名 (即将文件副本复制到 save 目录下并命名为 dir):

rsync -ai src/*.c save/dir

译者注: 但如果 src/*.c 可以匹配两个或多个文件,那么如果 save 目录存在,但其下没有 dir 目录,那么 save/dir 目录会被自动创建,并且复制所有文件到 save/dir 目录下。

为了不出现这种意外,要么在执行命令前要保证目标路径存在,要么在目标路径的最后加上一个斜杠:

rsync -ai src/*.c save/dir/

9. 传输顺序排列

rsync 总是将指定的文件按文件名排序然后加入到它的内部传输列表里。这个做法可以在指定多个 source 时合并同名目录的内容,使得去除重复文件名变得容易。但是,当文件传输顺序与命令行中给出的顺序不同时,可能会使人感到困惑。

如果你需要一个特定的文件先于另一个文件传输,要么将文件分成不同的 rsync 调用,要么考虑使用 --delay-updates (不影传输顺序,而是将要更新的文件的最新版本放在临时目录中,等到传输完毕后一次性更新所有需要更新的文文件)。

译者注: --delay-updates 选项让 receiver 将收到的所有文件放在一个临时的目录中,直到传输结束之前才一次性将它们全部移动到对应的目录下并重命名为各自对应的文件名。这个重命名的顺序是命令行中给出的顺序,这样间接地让命令行给出的传输顺序生效。

10. 多主机安全问题

rsync 采取措施来确保传输过程中被共享的文件请求受到保护,免受各种安全问题的影响。大多数潜在问题出现在接收端,rsync 采取措施确保正在传输的文件列表在请求的范围内。 译者注: 就是接收端容易出问题,但 rsync 能确保所有要传输的文件是用户要传输的。

自 rsync v3.1.2 开始,rsync 会在文件列表包含试图从传输顶部转义的绝对或相对路径时中止。此外,从 v3.2.5 开始,rsync 会对文件列表进行大于 2 次的安全检查,(1) 确保除了客户端请求的那些之外,没有额外的 source 被添加到传输列表中,以及 (2) 确保文件列表遵守 sender 收到的的排除规则。

译者注: 我也没搞懂作者说的这个 试图从传输顶部转义的绝对或相对路径 是啥。但是不读这一段不影响使用。

对于那些使用了版本号小于 v3.2.5 的 rsync 用户 (或者那些想要格外小心的用户),不信任远程主机时,最安全的做法是将远程文件复制到专用目标目录中。例如,不要将 rsync 副本复制到 home 目录中:

rsync -aiv host1:dir1 ~

将 host1-files 目录专用于远程内容:

rsync -aiv host1:dir1 ~/host1-files

查看 -trust-sender 可以获取更多内容。

小心: 使用 rsync 从大小写敏感的文件系统复制文件到大小写不敏感的文件系统不是特别安全。如果必须要这么做,那么应该使用 --no-links 来让 rsync 不处理链接 (译者注: 不拷贝链接到 dest) ,或通过 --munge-links 启用符号链接的修改 (要确定使用了正确的 loca 和 remote 选项)。如果符号链接名称与文件或目录重叠,这将防止 rsync 执行潜在的危险操作。但是它不能确保所有文件都有一个副本 (因为可能出现重名文件间的覆盖现象)。可能更好的解决方案是列出所有源文件并创建一个传递给 --files-from 选项的文件名安全列表。任何名字冲突的文件都需要使用多个副本复制到不同的目标目录。

译者注: 文档里没有专门讲解 --no-links 的段落,它其实是 --no-OPTION 的一种格式,这个选项有专门的讲解。 --links 的含义是拷贝链接文件 (对于软连接不解引用)。

译者注: 这个 --munge-links 选项中,我没查到 munge 是个什么意思,但是经过实践发现,它的作用是修改链接指向的地址。比如 remote-SRC 上有一个软链接 save/link@ -> a.c 拷贝到 localhost 后软链接变成了 save/link@ -> /rsyncd-munged/a.c。使用 --munge-links 将 save/link@ -> /rsyncd-munged/a.c 传到其他的 remote-DEST,这个链接又变回了 save/link@ -> a.c。

虽然 rsync 在忽略大小写的文件系统间复制文件可以正常工作,但是如果没有指定 --delete-during--delete-before 选项,rsync 可能会直接更新接收端的文件内容,而不修改文件名的大小写以匹配发送端发来的文件名。

11. 进阶使用

译者注: 直译原文的这一节不太好理解,有大量意译。可能有错。注意比照原文。

按照第一个 SRC 的格式,在第一个 SRC 之后再写其他的 SRC 参数 (可省略主机名),可以从一个远程主机传输多个路径到本地。比如,下面的写法效果相同:

rsync -aiv host:file1 :file2	host:file{3,4} /dest/
rsync -aiv host::modname/file{1,2} host::modname/extra /dest/
rsync -aiv host::modname/first ::extra-file{1,2} /dest/

译者注: 只能指定一个远程主机,不能指定多个远程主机。远程地址中省略主机名时,将取前一个远程地址的主机名作为它的主机名。

注意,虽然 rsync 命令中可以指定多个 SRC,但如果 SRC 中要使用 rsync module,那么这些 SRC 只能使用一个 rsync module。即,所有的 SRC 只能使用同一个 rsync module。如果第二个 SRC 省略 module 名称,那么它默认使用第一个 SRC 的 module 名称。比如上面的命令中 ::extra-file{1,2} 被补全后应该是 host::modname/extra-file{1,2}

老版本的 rsync (v2.6.9 及之前) 只允许指定一个 remote-SRC 字段。所以有些人将多个路径以空格为分隔符组合出一个长字符串作为 remote-SRC 的路径字符串,再使用 remote shell 的字符串切割功能,将这个长字符串拆回多个路径,来让 rsync 一次可以传输多个路径。现在不再支持这种不直观的行为。

从 v3.2.4 开始,remote-SRC 中的路径字符串不会再被 remote shell 拆分。因此,即使路径中包含空格,那么这个包含空格的路径也是远程 rsync 应该查找的路径:

rsync -aiv host:'a simple file.pdf' /dest/

对于已经使用了这个功能的老脚本要被新版 rsync 执行的情况来说。为新版本的 rsync 命令使用 --old-args 选项可以让新版本的 rsync 支持这个拆分引号内容的功能。或者,添加环境变量 RSYNC_OLD_ARGS=1RSYNC_PROTECT_ARGS=0 可以有一样的效果,新老版本同时支持这些环境变量。

12. 连接到 rsync daemon

也可以在没有 remote shell 的情况下使用 rsync 传输数据。在这种情况下,你将直接连接到 remote rsync daemon,通常在 873 端口上使用 TCP 传输数据。(显然,这要求 rsync daemon 运行在 remote host 系统上,参考下文的 通过 rsync daemon 接收数据 获取更多信息)

通过这种方式使用 rsync 与通过 remote shell 使用 rsync 有相同效果,除了:

  • 使用双冒号 ::rsync:// URL 语法,而不使用单冒号 : (单冒号对应使用 remote shell)
  • 路径中的第一个单词实际上是一个 module 名称
  • 有多个 remote SRC 是可以从第二个 remote SRC 开始使用省略主机名、module 名的简写,就像 进阶使用 一节说的那样
  • remote daemon 可能会在连接时输出 "message of the day"
  • 如果仅指定了主机名 (没有指定 module 名称和路径),程序将显示 remote daemon 可访问的 module 列表
  • 如果指定了一个 remote SRC 但没有指定 DEST,程序将显示 remote SRC 的 rsync daemon 匹配到的文件列表
  • 不能使用 --rsh (-e) 选项。这可以避免将连接类型从 socket 类型变成下一节 通过 remote shell 连接使用 rsync-daemon 中所说的类型

给一个例子,它复制了 remote module 为 "src" 的所有文件:

rsync -av host::src /dest

一些 remote daemon 的 module 可能需要认证。如果需要,连接时会收到一个密码输入提示。可以将被使用的密码设置为环境变量 RSYNC_PASSWORD 来避免密码输入提示,也可以使用选项 --password-file 选项指定密码所属的文件。这在写使用 rsync 的脚本时很有用。

警告: 在一些系统上,环境变量对所有用户可见。在这些系统上推荐使用 --password-file 选项。

将环境变量 RSYNC_PROXY 设置为指向 web 代理的 <hostname>:<port> 值,可以通过 web 代理建立连接。注意,web 代理的配置必须支持到端口 873 的代理连接。

还可以通过将环境变量 RSYNC_CONNECT_PROG 设置为希望运行的程序,使用该程序作为代理来建立与 rsync daemon 的连接,而不是直接使用套接字连接。字符串可能包含转义符 "%H" 以表示 rsync 命令中指定的主机名 (因此,字符串中要使用 "%%" 来替代单个 "%")。例如:

export RSYNC_CONNECT_PROG='ssh proxyhost nc %H 873'
rsync -av targethost1::module/src/ /dest/
rsync -av rsync://targethost2/module/src/ /dest/

上面的命令使用 ssh 在 proxyhost 上运行了 nc 命令,它将会转发所有数据到目标主机 (%H) 的 873 端口。

译者注: 这个环境变量的作用是,先从本机 ssh 到 proxyhost 上,再用 nc 命令监听从 ssh 流入的数据并转发到 %H 主机的 873 端口。本机运行 rsync 命令以后,rsync 的 socket 流量先被重定向到 proxyhost 上的 SSH 中,此时 nc 监听了 SSH 流入的数据,所以流量被重定向到了 proxy host 的 nc 中,再由 nc 转发到其他地方。

也要注意,如果设置了 RSYNC_SHELL 环境变量,那么 RSYNC_SHELL 值对应的 shell 程序将被用于运行 RSYNC_CONNECT_PROG 而不是使用 system() 调用默认的 shell。

13. 通过 remote shell 连接使用 rsync-daemon

有时,除了 remote shell 访问所需之以外,不允许任何系统建立任何新的 socket 链接。这个时候,rsync daemon 的多种特性 (比如 modules) 很有用。rsync 还支持使用 remote shell 连接到主机然后生成一个一次性使用的 rsync daemon server,该 server 希望在远程用户的 home 目录中读取其配置文件。如果想要加密 rsync daemon 传输的数据,这可能很有用,但由于 daemon 是由远程用户新启动的,因此可能无法使用 chroot 等功能或更改 daemon 使用的 uid。(对于加密 rsync daemon 传输的数据的另一种方式,考虑使用 SSH 将本地端口映射到远程机器上,并在该远程主机上配置常规的 rsync daemon,以便只允许来自 "localhost" 的连接)

译者注: 上面那段话,有三个内容。第一个,除了 shell 外不允许建立新 socket 连接意味着,rsync client 通过 remote shell 连接到 server 之后,就无法再启动 server 上的 rsync 了,这意味着 server 无法传输数据到本地。

译者注: 第二个,rsync 支持用 remote shell 连接到远程主机后,起一个临时的 rsync daemon,用完关掉。因为 rsync daemon 传输的数据不带加密,这个行为是为了利用 remote shell 的加密功能加密 rsync daemon 传输的数据。

译者注: 第三个,要加密 rsync daemon 传输的数据还可以先在主机上起一个只允许来自本地连接的 rsync daemon,然后利用 SSH 的端口转发功能连接到这个只允许本地连接的 rsync daemon 上再传输数据,这样可以利用 SSH 自带的加密方法加密 rsync daemon 传输的数据。

从用户的角度来看,通过 remote shell 连接 rsync daemon 传输数据使用的命令行语法与正常的 rsync daemon 传输几乎相同,唯一的例外是必须在命令行上使用 --rsh=command 选项显式设置 remote shell 程序。另外,在环境中设置 RSYNC_RSH 不会通过 remote shell 连接 rsync daemon 传输数据。例如:

rsync -av --rsh=ssh host::module /dest

要指定 remote shell 的用户,记得把前缀 user@ 放在 host 之前,这指定了 rsync-user 的值 (对于一个基于用户进行身份验证的 module 有效)。这意味着指定 remote shell 时必须指定 ssh 的 '-l user'选项,就像在下面这个例子中使用的简写版的 --rsh 选项:

rsync -av -e "ssh -l ssh-user" rsync-user@host::module /dest

"ssh-user" 将被用在 ssh 连接,"rsync-user" 将被用于登录到 "module"。

通过 remote shell 连接使用 rsync-daemon 的情况下,server 上临时的 rsync daemon 由访问 server 的 remote shell fork 出来。但是,当直接访问 rsync daemon 时,需要预先启动它。

译者注: 上段第一句话的原文是 In this setup, the daemon is started by the ssh command that is accessing the system (which can be forced via the ~.ssh/authorized_keys file, if desired). 我没搞清作者括号里的内容是想说啥。/

译者注: 文档中对于启用临时 rsync daemon 的条件没有特意标明,这里再强调一下。必须在命令行上使用 --rsh=command 选项显式设置 remote shell 程序,然后再在 SRC 或者 DEST 字段中指定 module 及路径 (即,使用 rsync daemon 的语法)。

14. 通过 rsync deamon 接收数据

在直接连接 rsync daemon 之前,首先要确保 rsync daemon 已经运行 (或者可能需要配置类似 inetd 的东西,以便为特定端口上的传入连接生成 rsync daemon)。对于如何启动用以处理到来的连接的 daemon 的完整信息可以在 rsyncd.conf(5) man 手册里找到。rsyncd.conf 是这个 daemon 的配置文件,它包含了如何运行 daemon 的完整细节 (包括独立配置和 inetd 配置)。

如果通过 remote shell 连接使用 rsync daemon 的话就没有必要手动启动一个 rsync daemon。

15. 例子

这里有一些如何使用 rsync 的例子。

要备份 home 目录,这个目录由大的 word 文件和邮件目录组成。将下面的命令加入到 cron 中设置每日执行即可:

rsync -aiz . bkhost:backup/joe/

从 remote host 移动文件到 localhost 要执行:

rsync -aiv --remove-source-files rhost:/tmp/{file1,file2}.c ~/src/

16. 选项摘要

下面是 rsync 中可用选项的简短摘要。后面的文章有详细说明。

译者注: 多数 summary 都说的很模糊,主要起目录的作用,如果需要了解某个选项请阅读详细说明。

--verbose, -v 让输出信息更详细

--info=FLAGS 调整命令执行时输出的 info 信息

--debug=FLAGS 调整命令执行时输出的 debug 信息

--stderr=e|a|c 更改 stderr 的输出模式 (默认: errors)

--quiet, -q 不显示 error 之外的信息

--no-motd 忽略 rsync daemon 的 MOTD 信息

--checksum, -c 基于校验决定是否更新文件,而不是修改时间和大小

--archive, -a 存档模式。它是 -rlptgoD 选项组合的简写 (不包括 -A, -X, -U, -N, -H)

--no-OPTION 关闭隐藏选项 (例如 --no-D)

--recursive, -r 递归地解析目录

--relative, -R 使用相对路径

--no-implied-dirs 使用 --relative 时不修改 DEST 上已有目录的属性

--backup, -b 制作备份 (详见 --suffix--backup-dir)

--backup-dir=DIR 让备份文件使用 DIR 指定的路径

--suffix=SUFFIX 传输文件时备份文件的后缀 (不使用 --backup-dir 选项时默认是 ~) (传输文件时的临时文件的文件名就是要被传输的文件的文件名后面加一个该选项指定的符号)

--update, -u 如果接收端的文件比发送端的日期新,不更新该文件

--inplace 直接将数据写入目标文件,而不是先写入临时文件

--append 当接收端文件大小小于发送端文件时,只更新两者长度差的部分到接收端的文件上

--append-verify--append 的行为类似,但是在传输前会比较接收端已有数据的校验和是不是符合发送端的前半段,如果校验和不一致,使用 --inplace 的方式传输数据

--dirs, -d 不递归地传输目录

--old-dirs, --old-d 在与版本较低的 rsync 通信时,行为类似于 --dirs 选项

--mkpath 在 DEST 上创建 DEST 指定的路径字符串中不存在的路径

--links, -l 将符号链接拷贝为符号链接

--copy-links, -L 将符号链接解引用,即将符号链接拷贝为其指向的目标

--copy-unsafe-links 只有 unsafe 的符号链接会被传输 译者注: 会对链接解引用

--safe-links 只有 safe 的符号链接会被传输 译者注: 不对链接解引用

--munge-links 给被复制的符号链接的目标地址添加额外的内容,让被复制后的符号链接更安全,并且不可使用

--copy-dirlinks, -k 让发送端对链接到目录的符号链接解引用,就像这个指向目录的符号链接真的是一个目录一样

--keep-dirlinks, -K 让已经存在于接收端的,指向目录的符号链接像一个真正的目录那样工作

--hard-links, -H 让 rsync 在 SRC 中查找具有硬链接的文件并将它们再在 DEST 上链接在一起

--perms, -p 让接收端为传输的文件设置与发送端一样的权限

--fileflags 在传输文件时保留文件的 file-flags (chflags)

--executability, -E 未指定 --perms 选项时,在接收端保留普通文件的执行权限

--chmod=CHMOD 让 rsync 在传输时应用一个或多个逗号分隔的 chmod 模式到要被传输的文件

--acls, -A 更新接收端文件的 ACL 属性使之和发送端对应文件的 ACL 属性一致

--xattrs, -X 更新接收端文件的扩展属性使之和发送端对应文件的扩展属性一致。

--owner, -o 将接收端文件的所有者设置为和源文件一样,但要求接收端的 rsync 以 super user 身份运行

--group, -g 将接收端文件的属组设置为和源文件一样,但要求接收端的 rsync 以 super user 身份运行

--devices 让 rsync 可以传输 character device 和 block device 到接收端上,以在接收端重新创建这些设备

--copy-devices 让发送端的 rsync 按照常规文件来处理 device,允许将 device 内容拷贝到接收端的普通文件中

--write-devices 让接收端的 rsync 按照常规文件来处理 device,允许将文件数据写入 device 中

--specials 传输特殊文件,比如 named socket, fifo

-D 等于 --devides --specials 一起用

--times, -t 让 rsync 将 mtime 随文件一起传输给 receiver,使得目标文件的 mtime 和源文件一样

--atimes, -U 让 rsync 将 atime 随文件一起传输给 receiver,使得目标文件的 atime 和源文件一样

--open-noatime 如果系统支持的话,让 rsync 以 O_NOATIME flag 打开文件以避免改变要被传输的文件的 atime

--crtimes, -N 让 rsync 在接收端收到的文件上设置于发送端相同的 ctime

--omit-dir-times, -O 让 rsync 在保留文件 mtime, atime 和 ctime 时,忽略目录的这些属性

--omit-link-times, -J 让 rsync 在保留文件 mtime, atime 和 ctime 时,忽略符号链接的这些属性

--super 让接收端尝试 super-user 的行为,即使接收端的 rsync 并不是以 super-user 的身份启动的

--fake-super 让 rsync 根据需要,通过附加到每个文件的特殊扩展属性来保存/恢复特权属性,从而模拟 super-user 行为

--sparse, -S 让 rsync 尝试高效地处理稀疏文件,让他们在接收端可以占用更小的空间

--preallocate 让接收端的 rsync 在每一个文件传输前预先分配空间

--dry-run, -n 让 rsync 模拟运行,而不改变任何数据,并且产生像 rsync 真正运行时那样的输出

--whole-file, -W 禁用 rsync 的增量传输功能,让 rsync 传输整个文件的所有数据

--checksum-choices=STR 在本地传输时,默认会启用 --whole-file ,这个选项在本地传输时禁用 --whole-file 选项

--one-file-system, -x 让 rsync 不跨文件系统递归

--block-size=SIZE, -B 强制 rsync 在增量传输时使用 SIZE 指定的 block size

--rsh=COMMAND, -e 允许用户选择 local rsync 与 remote rsync copies 交互要使用的 remote shell

--rsync-path=PROGRAM 这个选项指定了在 remote 主机上用哪个命令来启动 rsync

--existing 让 rsync 不创建接收端不存在的文件与目录

--ignore-existing 让 rsync 不更新已经在接收端上的文件。但会传输接收端没有的文件,已有的目录也会被更新

--remove-sources-files 让 rsync 在将文件传输到接收端之后,删除发送端的对应文件 (不删目录)

--del--delete-during 的别称

--delete 让 rsync 删除接收端的多余文件 (指没有在发送端出现过的文件),但只对那些被同步的目录生效

--delete-before 让 rsync 在传输开始前先删除接收端对应的文件

--delete-during 让 rsync 在传输期间增量地删除接收端的文件

--delete-delay 让 rsync 在传输期间计算要在接收端被删除的文件 (与 --delete-during 类似),然后在传输完成后删除要被删除的文件

--delete-after 让 rsync 在所有传输都完成后,再删除文件

--delete-excluded 此选项将任何 unqualified exclude/include 规则转换为不影响接收端删除行为的 server 端规则 译者注: 这个选项告诉 rsync 即使文件在发送端被 --exclude 排除了,也要在接收端将其删除

--ignore-missing-args 遇到发送端传输列表里有,但是文件系统上找不到的文件时,不报错,继续运行

--delete-missing-args 这个选项隐含 --ignore-missing-args 选项,但比它做得更多: 每一个未在发送端找到的参数都会变成一个接收端对应文件的删除请求

--ignore-errors 让使用了 --delete 的 rsync 即使遇到 I/O 异常也继续删除文件

--force-delete 如果接收端的非空目录与发送端的文件同名,删除接收端的非空目录

--force-change 让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 user-immutable 和 system-immutable 标志

--force-uchange 让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 user-immutable 标志

--force-schange 让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 system-immutable 标志

--max-delete=NUM 让 rsync 不要删除超过 NUM 数量的文件或目录

--max-size=SIZE 让 rsync 不传输任何大小大于 SIZE 的文件

--min-size=SIZE 让 rsync 不传输小于 SIZE 大小的文件

--max-alloc=SIZE 更改分配内存大小的限制

--partial 让 rsync 接着上次已经传输的部分继续传输剩余的部分

--partial-dir=DIR 让 rsync 先把文件传输到 DIR 目录中,而不是直接写入 DEST 指定的路径中。在被打断后的下一次传输中,rsync 会从 DIR 目录中找到未传输的文件,接着上次的进度继续传输,传输完成后 DIR 目录会被删除

--delay-updates 将每个要被更新的文件放入一个临时目录,待传输全部完成之后,所有在临时目录中的文件会被以重命名的方式移动到指定位置

--prune-empty-dirs, -m 让接收端的 rsync 从文件列表中删除空目录,包括没有非目录子项的嵌套目录

--numeric-ids 让 rsync 传输 uid 和 gid,而不是字符格式的 username 和 groupname

--usermap=STRING 允许自定义用户映射

--groupmap=STRING 允许自定义组映射

--chown=USER:GROUP 强制更改所有要被传输的文件的所有权为指定的用户和组

--timeout=SECONDS 设置 IO 超时的最大时间,单位为秒

--contimeout=SECONDS 设置 rsync 连接 rsync daemon 的等待超时时间

--ignore-times, -I 让 rsync 不进行 "quick check",这会让所有文件都被更新

--size-only 让 rsync 只根据文件大小是否改变来判断是否要传输文件

--modify-window=NUM, -@ 比较两个时间戳时,rsync 在两个文件的时间戳差值的绝对值不大于该选项指定的值的时候,认为这两个时间戳相等

--temp-dir=DIR, -T 让 rsync 在接收端创建对应文件的临时副本时使用 DIR 作为临时目录存储临时副本

--fuzzy, -y 让 rsync 为未找到的任何接收端的目标文件查找基础文件

--compare-dest=DIR 让 rsync 使用 DEST 上的 DIR 作为额外的层次结构

--copy-dest=DIR--compare-dest 接近,但 rsync 会从接收端的 DIR 目录中以本地拷贝的方式拷贝未改变的文件到接收目录中

--link-dest=DIR--copy-dest 接近,但未更改的文件会从 DIR 硬链接到接收目录

--compress, -z 向 remote 侧传输文件数据时压缩数据

--compress-choice=STR 被用于取消使用 --compress 选项时默认会做的压缩算法协商,并且使传输的两端使用选项中指定的压缩算法

--compress-level=NUM 明确地指定压缩算法的级别

--skip-compress=LIST 指定要被压缩的文件的后缀的名列表,这个后缀列表会覆盖默认的后缀列表

--cvs-exclude, -C 使用与 CVS 类似的算法来确定是否应忽略文件

--filter=RULE, -f 允许用户添加规则以有选择地从要传输的文件列表中排除某些文件

-F 用一次是 --filter='dir-merge /.rsync-filter' 用两次是 --filter='dir-merge /.rsync-filter' --filter='exclude .rsync-filter'

--exclude=PATTERN--filter 选项的简化版,它指定了一个排除规则,并且它不解析普通的筛选规则

--exclude-from=FILE 指定了一个包含 exclude 规则的文件

--include=PATTERN--filter 选项的简化版,它指定了一个包含规则,并且它不解析普通的筛选规则

--include-from=FILE 指定了一个包含 include 规则的文件

--files-from=FILE 制定了一个文件,文件中有要被传输的文件的精确列表,FILE 使用 - 表示从标准输入读取列表

--from0, -0 从文件中读取规则或文件名时以空字符 (\0) 终止

--old-args 让 rsync 不保护 remote 端的 arg 值不受意外分词或其他误解的影响

--secluded-args, -s 通过 protocol (而不是 remote shell 命令行) 将所有文件名和大多数选项发送到远程 rsync

--trust-sender 禁用 local client 端对 remote 发送端生成的文件列表执行的两项额外验证检查

--copy-as=USER[:GROUP] 让 rsync 使用 USER 和 GROUP (如果在冒号后指定了的话) 进行复制操作

--address=ADDRESS 指定 rsync 绑定的 IP 地址或主机名

--port=PORT 指定 rsync daemon 在所在主机上监听的 TCP 端口

--sockopts=OPTIONS 自定义套接字选项

--blocking-io 在加载 remote shell 传输时,让 rsync 使用阻塞 I/O

--outbuf=N|L|B 设置输出缓存的模式

--stats 让 rsync 输出文件传输过程中的详细统计数据

--8-bit-output, -8 让 rsync 在输出中保留所有高位字符的非转义形式

--human-readable, -h 让输出中的数字被转换成容易被人类阅读的格式

--progress 让 rsync 输出传输进度信息

-P 等于 --partial --progress 一起用

--itemize-changes, -i 请求显示对每个文件所做的更改的简单逐项列表

--remote-option=OPT, -M 让某些选项仅在传输的一侧生效

--out-format=FORMAT 允许用户准确指定 rsync client 在每次更新条目时向用户输出的内容

--log-file=FILE 在 FILE 中记录 rsync 的行为

--log-file-format=FMT 允许用户指定准确的每个更新的日志格式到 --log-file 选项指定的文件中

--password-file=FILE 让 rsync 可以通过 FILE 中存储的密码连接到 rsync daemon

--list-only 让 rsync 列出源文件而不传输它们

--bwlimit=RATE 指定 daemon 发送到套接字的数据的最大传输速率

--stop-after=MINS 让 rsync 在指定的分钟数过去后停止传输

--stop-at=y-m-dTh:m 让 rsync 在指定的日期和时间停止传输

--fsync 每写完一个文件以后执行一次 fsync

--write-batch=FILE 记录一个文件,该文件以后可以使用 --read-batch 选项应用到另一个完全相同的目标

--only-write-batch=FILE--write-batch 的工作方式类似,但在创建批处理时不会对目标系统做任何更新

--read-batch=FILE 应用存储在文件 FILE 中的所有更改,FILE 文件是先前由 --write-batch 生成的

--protocol=NUM 强制使用指定的协议版本

--iconv=CONVERT_SPEC 在字符集之间转换文件名

--checksum-seed=NUM 将校验和种子设置为整数 NUM

--ipv4, -4 在创建 socket 或运行 ssh 时优先使用 IPv4

--ipv6, -6 在创建 socket 或运行 ssh 时优先使用 IPv6

--version, -V 输出 rsync 版本号与其他信息后退出

--help, -h (*) 输出简短的关于 rsync 选项的帮助信息后退出

rsync 也可以以 daemon 模式运行,在这个情况下,有以下选项可用:

--daemon 让 rsync 作为守护进程运行

--address=ADDRESS 指定要绑定到的特定 IP 地址 (或主机名)

--bwlimit=RATE 指定 daemon 发送到套接字的数据的最大传输速率

--config=FILE 显示指明要使用的配置文件

--dparam=OVERRIDE, -M 启动 rsync daemon 时设置 daemon 的配置参数

--no-detach 启动 rsync daemon 时不让 daemon 成为后台进程

--port=PORT 指定 rsync daemon 要监听的 TCP 端口号,而不是默认的 873 端口

--log-file=FILE 让 rsync daemon 使用指定的日志文件,而不是使用配置文件中的 log file 字段的设置

--log-file-format=FMT 让 rsync daemon 使用给定的 FORMAT 字符串,而不是使用配置文件中 log format 字段的设置

--sockotps=OPTIONS 覆盖了 rsyncd.conf 文件中 socket options 字段的设置,并具有相同的语法

--verbose, -v 增加了 daemon 在启动阶段记录的信息量

--ipv4, -4 rsync daemon 监听连接的传入套接字时优先使用 IPv4

--ipv6, -6 rsync daemon 监听连接的传入套接字时优先使用 IPv6

--help, -h--daemon 之后使用时,输出一个简短的帮助页面,描述启动 rsync daemon 可用的选项

17. 选项

rsync 接受长选项 (双减号 -- 号后接单词) 和短选项 (单减号 - 号后接字母)。下面是完整的选项列表。如果一个功能同时有长选项写法和短选项写法,那么用逗号分隔这个功能的两个写法。有些功能只有长选项,没有短选项。如果选项可以接收参数,则该参数只能列在长选项之后,即使还必须为短变量指定该参数。指定参数时,可以使用 --option=param 样式,也可以将 = 替换为空格。参数可能需要以某种方式引用,才能被 shell 正确解析。记住,文件名中的前导波浪号 (~) 由 shell 替换,因此 --option=~/foo 中的波浪号不会被更改为 home 目录 (用空格替代等号可使之正常解析为 home 目录)。

--help

输出简短的关于 rsync 选项的帮助信息后退出。当只有这一个选项时,也可以使用短选项 -h 来代替长的选项 --help (因为在有多个选项时 -h 的含义是 --human-readable)

--version, -V

输出 rsync 版本号与其他信息后退出。使用两次这个选项,即 --version --version 或者 -VV 或者 -V -V 则以 JSON 格式输出版本信息。

输出的信息包括有哪些在编译时支持了的兼容性、支持的功能优化、支持的压缩算法、支持的校验和算法、rsync 网站的链接以及一些许可证/版权信息。

--verbose, -v

这个选项可以在 rsync 传输文件时显示更多的信息。默认情况下,rsync 在工作时不输出信息。使用这个选项可以让 rsync 输出什么文件要被传输,以及传输完成后再输出一个摘要信息。这个选项用两次,即 -vv 或者 -v -v 除了前面提到的信息之外,还会输出有哪些文件被跳过,并且在最后的摘要中显示更多信息。多余两次地使用这个选项只有在调试 rsync 的时候才会用到。

传输结束后显示的摘要信息显示了以 byte 表示的向 remote rsync 传输的数据量 (rsync 工作在本地模式时,remote rsync 就是本地的接收端),从 remote rsync 接受的数据量,在 rsync 运行期间每秒传输的 byte 数量。第二行显示了以 byte 表示的传输的数据总量。第二行显示了总大小 (以 byte 为单位),它是 rsync 考虑传输的所有文件大小的总和。还有一个值是 "speedup",值为总文件大小除以发送和接收字节的总和 (这个值越大越好)。注意,使用 --human-readable--no-human-readable 可以使这些值更容易或更不容易被人阅读。

译者注: 摘要第一行显示三个数字,第一个是传输的数据总量,第二个是接受的数据总量,第三个是传输速度。由于 rsync 在传输过程中要传输很多控制信息,而且传输过程中有数据压缩,所以第一个值总是比第二个值大。

译者注:第二行的第一个值是 rsync 统计的的传输的文件的总大小,这个值只统计文件大小,控制信息的大小不算进去。第二行的第二个值是一个比值,值越大意味着传输时的资源消耗越少。

译者注: --human-readable 可以让 byte 在合适时转换成 MB, GB 等容易阅读的格式。 --no-human-readable 会去除摘要中能让阅读变得轻松的部分。

在现在的 rsync 中,这个选项相当于 --info--debug 的部分组合。除了使用 --verbose 之外,还可以使用这两个较新的选项,或者只使用这两个新选项。因为 --info--debug 的所有选项的优先级都高于 -v 选项,所以 -v 的部分设置可能被这两个选项覆盖。执行 rsync --info=helprsync --debug=help 可以看到有哪些配置可以用。

但是,请记住,rsync daemon 配置文件 rsync.conf 中的 max verbosity 的值限制了 rsync daemon 指定的 --info --debug 选项中的 FLAGS 的级别。例如,如果 max verbosity 的值为 2,那么在 rsync daemon 的日志中,任何详细程度大于 -vv 的级别的 --info --debug 中的 FLAGS 都将降级为 -vv 对应的级别。

--info=FLAGS

这个选项可以在 rsync 输出的传输信息方面做更细颗粒度的控制。值的格式是关键字后跟描述详细级别的数字,0 意味着不输出,1 是默认的详细程度,大于 1 表示输出更详细的信息 (如果该关键字支持指定详细级别的话)。执行 rsync --info=help 可以查看所有可用的关键字名称,这些关键字代表着输出什么内容,以及这些关键字支持的详细级别。下面是一些例子:

rsync -a --info=progress2 src/ dest/
rsync -avv --info=stats2,misc1,flist0 src/ dest/

注意 --info=name 的输出受 --out-format--itemize-changes (-i) 两个选项影响。这两个选项的说明描述了它们如何影响输出。

这个选项从 rsync v3.1.0 被引入,所以旧于该版本的,在 server 侧的 rsync 可能会拒绝这个控制颗粒度的选项 (如果选项里指定了一个或者多个关键字但是 server side 的 rsync 无法理解的话)。另请参阅上面提到的处理 rsync daemon 时提到的 "max verbosity" 属性。

--debug=FLAGS

这个选项可以在 rsync 输出的 debug 信息方面做更细颗粒度的控制。值的格式是关键字后跟描述详细级别的数字,0 意味着不输出,1 是默认的详细程度,大于 1 表示输出更详细的信息 (如果该关键字支持指定详细级别的话)。执行 rsync --debug=help 可以查看所有可用的关键字名称。下面是一些例子:

rsync -avvv --debug=none src/ dest/
rsync -avA --del --debug=del2,acl src/ dest/

注意,有些 debug 信息只会在使用 --stderr=all 的时候输出,特别是那些与 I/O 和 buffer debug 相关的信息。

自 rsync v3.2.0 开始,这个选项不再被自动应用的 server 侧,目的是允许用户在 client 侧和 server 侧指定不同的 debug 输出参数,以及在两侧 rsync 版本不同时,允许指定仅存在于某一侧的参数。如果想要在两侧使用相同的 debug 参数,使用大括号扩展是一种好方式,下面的例子在 zsh 和 bash 都能正常工作:

rsync -aiv {-M,}--debug=del2 src/ dest/

译者注: 可以用 echo {-M,}--debug=del2 命令来看大括号展开以后是什么。这个 -M 见后面的 --remote-option=OPTION, -M 选项。

--stderr=errors|all|client

这个选项控制哪个进程要向 stderr 输出信息,并且是否要重定向 info 信息到 stderr 中。可以使用参数的第一个字母作为缩写,即 errors|all|client 可缩写为 e|a|c 。这三个参数的含义是:

  • errors (默认) 让所有的 rsync 进程直接向 stderr 发送信息。即使 rsync 进程处于 remote 侧,处于该侧的 rsync 进程也直接向 stderr 发送信息。info 信息通过协议流被发送到 client 侧。如果 stderr 不可用 (比如直接通过 socket 连接到 rsync daemon 的情况),error 信息的发送方式会回落到通过协议流发送。
  • all 所有的 rsync 进程消息 (info 和 error) 直接写入 stderr。这会导致 stderr 处于 line-buffered 模式而不是 raw 模式,并不再按文件句柄划分 info 和 error 消息。对于需要调试或使用多个详细级别的情况来说,此选项可以避免堵塞传输流 (应该可以防止死锁导致的程序暂停)。它还允许 --debug 输出一些额外的 I/O 相关的消息。
  • client 让所有的 rsync 进程的消息都通过协议流传送到 client 侧。由一个 client 来输出所有的消息,error 在 stderr 输出,info 在 stdou 输出。这在旧版 rsync 中是默认选项,但在消息前传输传输大量数据可能导致 error 延迟传输。如果正向一个旧版的 rsync 传输文件,使用 --stderr=all 更好,因为该习惯用法已经存在于多个版本中。

这个选项自 rsync v3.2.3 被加入。此版本还开始将非默认设置转发到远程端,尽管 rsync 使用向后兼容选项 --msgs2stderr--no-msgs2stderr 分别表示 all 参数和 client 参数。较新的 rsync 将继续接受这些较旧的选项名称以保持兼容性。

--quiet, -q

此选项可减少传输过程中提供的信息量,特别是抑制来自远程服务器的信息。从 cron 调用 rsync 时,此选项很有用。

--no-motd

这个选项影响了 rsync daemon 传输开始时 client 侧输出的信息。它抑制了 motd (message-of-the-day) 信息的输出,但也影响了 rsync daemon 返回的 rsync host:: 请求到的 module 列表 (受限于 rsync 协议),因此,如果想要从 rsync daemon 中获取 rsync daemon module 列表,不要使用这个选项。

--ignore-times, -I

通常,rsync 会忽略具有相同大小与相同修改时间 (时间戳) 的文件。该选项让 rsync 不进行 "quick check",让所有文件都被更新。

译者注: 注意,这个选项不只是忽略时间戳的不同,也不比较大小是否相同了。它让 rsync 将 SRC 指定的文件,不论 DEST 有没有、一样不一样,都重新复制过去。

这个选项很容易与 --ignore-existing--ignore-non-existing 搞混,这两个选项会让 rsync 传输更少的文件,而 --ignore-times 会让 rsync 传输更多的文件。

--size-only

让 rsync 只根据文件大小是否改变来判断是否要传输文件。rsync 原本使用 "quick check" 算法,根据文件大小和文件修改时间判断,这两个属性只要有一个不同,这个文件就要被传输。这个选项在创建目录镜像并且不需要时间戳完全一致时很有用。

--modify-window=NUM, -@

在比较两个时间戳的时候,rsync 在两个文件的时间戳差值的绝对值不大于该选项指定的值的时候,认为这两个时间戳相等。默认值是 0,只匹配整数秒。如果使用了一个负值 (并且接收端的 rsync 版本大于 3.1.3) 那么这个负值的绝对值代表纳秒。将值设置为 1 在 FAT 文件系统间相互复制文件时非常有用,因为 FAT 以 2 秒分辨率表示时间 (允许时间与原始时间最多相差 1 秒)。

译者注: FAT 文件系统时间戳的秒数以 2 秒为一个增量。比如,一个 SRC 文件的时间戳的秒数是 13.55 ,它作为 DEST 在 FAT 文件系统里会被存储为 12 。rsync 在计算时间戳时,如果这个选项没有用负数,那么就只从时间戳里取秒数。即,从 SRC 文件取得秒数 13,从 DEST 文件取到时间戳 12,相减取绝对值得 1 <= modify-window 认为这两个文件相同。实际上这两个文件也相同,只是因为文件系统不同导致它们的时间戳不同,这个选项可以应对这个情况。

如果想要默认使用纳秒的精度来比较时间戳,可以创建一个 ~/.popt 文件并加入以下内容:

rsync alias -a -a@-1
rsync alias -t -t@-1

译者注: 上面的代码表示将 -a 定义为 -a@-1 (写开就是 -a -@-1)。

使用这个文件的话,如果要在 ext3 和 ext4 之间进行复制,或者接收端的 rsync 版本小于 3.1.3,就需要指定 --modify-window=0 (-@0) 覆盖它,使其忽略纳秒。

--checksum, -c

这个选项改变了 rsync 判断文件是否改变并且是否需要传输的方式。rsync 原本使用 "quick check" 算法,根据文件大小和文件修改时间判断,这两个属性只要有一个不同,这个文件就要被传输。这个选项让 rsync 在文件大小一致时,根据文件的 128 bit 校验和是否一致来判断是否要传输文件。这意味着发送端和接收端都需要产生许多 I/O 以读取文件的所有数据计算校验和,这会导致严重的性能下降。 (为传输文件而产生任何 I/O 之前,计算校验和这个步骤会先产生 I/O)

发送端在做文件系统扫描以构建可获取的文件列表时计算校验和。接收端在扫描被更改的文件时计算校验和,它会给那些与发送端的文件大小相同的文件生成校验和: 大小不同的文件与校验和不同的文件会被传输。

注意,rsync 总会在文件传输完成后,通过计算整个文件的校验和来以确认每一个要被传输的文件在接收端被正常重构。这个传输完成后的验证文件是否被正常重构的行为,与使用此选项时,rsync 在传输前所执行的是否需要更新此文件的检查无关。

client 和 server 之间自动协商计算校验和所使用的算法,但可以使用 --checksum-choice (--cc) 或介绍该选项的章节中提及的环境变量来指定算法。

--archive, -a

它是 -rlptgoD 选项组合的简写。它让 rsync 递归并且保留几乎所有内容的传输文件。要注意,ACLs (-A), xattrs (-X), atimes (-U), crtimes (-N) 都不保留,也不保留硬链接。还不包括 --fileflags(译者注: 不保留 fileflag)

译者注: 不保留硬链接的意思是,硬链接在接收端会被解引用,变成源文件的一份拷贝。

--no-OPTION

关闭一个或多个隐含的选项。并不是所有选项都能用 no- 关闭,但很多都可以,包括那些隐含了其他选项的选项 (如 --no-D, --no-perms) 或者不同环境下有不同默认值的选项 (如 --no-whole-file, --no-blocking-io, --no-dirs)。 no- 后面既可以接短格式选项,也可以接长格式选项 (如 --no-R 等价于 --no-relative)。

例如,要使用 -a 选项但不使用它的隐含选项 -o (--owner),即让 -a 等价于 -rlptgD ,可以指定 -a --no-o (或 -a --no-owner)。

选项的顺序非常重要: 如果指定 --no-r -a 则最终启用了 -r 选项,与之相反的是 -a --no-r 。同样需要注意的是 --files-from 的副作用,它的位置顺序不重要,因为它影响了某些选项的默认行为,并轻微改变了 -a 的意义 (见 --files-from 选项的说明)。

--recursive, -r

让 rsync 递归地复制目录。 --dirs (-d) 选项描述了对于单一目录来说允许的扫描行为。

--inc-recuesive 选项讨论了要传输的增长的文件列表的增量递归。

--inc-recursive, --i-r

这个选项明确地在扫描文件的时候使用增量递归。使用 --recursive 选项并且 rsync 的接收端和发送端的版本都高于 3.0.0 时,默认启用增量递归。

增量递归比之前使用了更少的内存,并且在程序启动后更快地开始传输文件 (因为在传输开始之前不需要扫描整个目录结构)。如果不使用递归,这个选项没有意义。

有些选项要求 rsync 先扫描完整的目录结构,所以使用这些选项时,增量递归不起作用: --delete-before (旧版本中 --delete 的默认模式), --delete-after, --prune-empty-dirs, --delay-updates

为了让 --delete 兼容增量递归,rsync v3.0.0 将 --delete-during (自 v2.6.4 被引入) 作为 --delete 的默认模式。

增量递归的一个副作用是,在被递归扫描的目录中的任何缺失的子目录都默认在递归这个子目录之前被创建。这个与非增量递归相比较早建立子目录的行为允许 rsync 立即设置目录的修改时间而不必推迟到递归地复制文件全部完成。然而,这些早期建立的目录还没有 completed mode, mtime 或者所有权设置。在真正开始复制这个子目录前,这个子目录有更多的限制。通使用 --omit-dir-times 选项可以让 rsync 不在真正开始这个子目录前创建这个子目录。

译者注: 我没找见这个 completed mode 是个什么东西。

增量递归可以被 --no-inc-recursive (--no-i-r) 选项禁用。

--no-inc-recursive, --no-i-r

禁用 --recursive 选项指定的新的增量递归算法。这让 rsync 在开始传输文件之前扫描整个文件列表。详见 --inc-recursive 选项。

--relative, -R

使用相对路径。在 SRC 指定的路径会整个被传输到 server,而不只是传输作为 SRC 指定的路径的最后一个部分的文件名。这尤其被用于同时传输几个不同目录的情况下。比如,这些命令:

rsync -av /foo/bar/baz.c remote:/tmp/

这条命令会在 remote 这台机器的 /tmp 目录下创建一个名为 baz.c 的文件。但如果使用这个命令:

rsync -avR /foo/bar/baz.c remote:/tmp/

那么 rsync 会在 remote 这台机器上创建 /tmp/foo/bar/baz.c 文件,这个文件的路径包含了它在 SRC 中指定的完整路径。这些额外的路径被叫做 "implied directories" (比如这个例子中的 "foo" 和 "foo/bar" 目录)。

译者注: implied directories 在后文统一被称作 "隐含路径" 。

译者注: 比如有 /root/save1/d1/d11/d111 这个路径,现在工作路径是 /root/save1 那么使用 rsync -avi -R d1 <dest>:/tmp 则在 <dest> 上会生成 /tmp/d1/d11/d111 路径。隐含路径的参数以 SRC 中使用的路径参数为准。但如果使用 rsync -avi -R ~/save1/d1 <dest>:/tmp> 那么 <dest> 上会生成 /tmp/root/save1/d1/d11/d111 路径。即,路径中有可以展开的字符的话,这个字符会被展开,这个过程由 shell 完成。

译者注: 下面这段我翻译的和作者说的可能不是一回事,注意比对原文。

自 rsync v3.0.0 开始,rsync 总是发送这些隐含路径作为文件传输列表中真正的路径,即使发送端指定的路径中包含符号链接。这在你没有意识到要传输的文件路径中包含符号链接,但还要传输这个文件的到完整的隐含路径时,避免了一些不被期望的行为。 译者注: 这里指的是,如果路径字符串中含有符号链接,那么这个符号链接会被处理成普通目录。注意,这里说的是路径字符串的中间由符号链接,完整路径字符串指向的是一个常规文件或目录,要传输的是常规文件或目录;而不是路径字符串最终指向的就是一个符号链接,这种情况下传输的只是一个符号链接,而不是文件或目录。 如果你想要复制发送侧的符号链接,就需要在 SRC 中指定符号链接的路径、以及该符号链接链接到的真正目录的路径。 译者注: 下面这一句和上面那一句没有联系。 如果发送端使用的是比 v3.0.0 更低版本的 rsync,可能需要使用 --no-implied-dirs 选项。 译者注: 在发送端版本低于 v3.0.0 且 SRC 路径中带符号链接时, --no-implied-dirs 选项可以让接收端将所有链接到目录的符号链接都处理成普通目录。这个选项影响的是接收端,不是发送端,这里不多说。

译者注: 就是说在生成传输列表的时候,所有文件,包括符号链接,在传输列表里记录的路径字符串都是隐含路径。比如有 /root/save1/d2/d22/{11,22,33} 这三个文件,而 /root/save1/d3 是指向 /root/save1/d2 的软连接。现在工作目录是 /root/save1,使用 rsync -avi -R d3/d22 <dest>:/tmp 后 <dest> 会得到 /tmp/d3/d22/{11,22,33} 三个文件。这个例子中,路径字符串 d3/d22 中含有符号链接,最终符号链接被处理成了普通目录。

译者注: 但如果使用 rsync -avi- R d3 <dest>:/tmp 那么最终在 <dest> 的 /tmp 路径下就只会得到一个 /tmp/d3@->d2 符号连接。因为 d3 就是一个符号链接,而不是一个常规文件或目录。

译者注: 想要完全复制发送侧的符号链接就需要使用 rsync -avi -R d3 d2 <dest>:/tmp 才行。这样 <dest> 会得到 /tmp/d3@->d2 和 /tmp/d2/d22/{11,22,33} 。此外 ~rsync -avi -R . <dest>:/tmp~ 也会得到相同的结果,因为 ./ 路径中,既包含了符号链接 d3 也包含了符号链接链接到的真正目录 d2。/

也可以在 SRC 的路径字符串中指定要作为隐含路径的部分。自 rsync v2.6.7 开始,可以通过在 SRC 的路径字符串中加入一个点和一个斜杠来来指明隐含路径:

rsync -avR /foo/./bar/baz.c remote:/tmp/

这条命令会下来 remote 这台机器上创建 /tmp/bar/baz.c 文件。注意,点后面一定要跟斜杠。老版的 rsync 不支持该功能,只能在执行 rsync 前通过切换目录来达到同样的效果:

(cd /foo; rsync -avR bar/baz.c remote:/tmp/)

上面那条命令的括号可以将括号内的命令放在子 shell 中执行,这样可以让 cd 命令不会影响括号之外的命令。如果要从老版的 rsync 中拉取文件,使用这个习惯用法 (前提是远程机器没有使用 rsync daemon):

rsync -avR --rsync-path="cd /foo; rsync" remote:bar/baz.c /tmp/

--no-implied-dirs

它影响 --relative 选项的行为。SRC 中指定的隐含路径的属性不被传输。这意味着如果 DEST 上已经有 (一部分或者全部的) 隐含路径,那么已有路径元素不会被改变,并且如果 DEST 上只有隐含路径的一部分,那么没有的路径会被使用默认的属性创建。这甚至允许发送端和接收端的隐含路径有很大的不同,比如接收端的隐含路径中有符号链接。 译者注: 路径中有符号链接意味着文件会被传输到接收端的其他地方。

比如,rsync 要传输 path/foo/file 文件,在使用 --relative 选项的情况下 path 和 path/foo 就是隐含路径。如果在接收端 path/foo 是一个链接到 bar 的符号链接,在不使用 --no-implied-dirs 选项的情况下,接收端的 path/foo 符号链接会被删除,然后重新创建一个普通目录 path/foo 来接收 file 文件;在使用 --no-implied-dirs 选项的情况下,接收端的 rsync 看到 path/foo 路径已经存在,就会直接在这个路径下接受 file 文件,尽管接收端实际存放 file 的路径是 path/bar。另一个保持接收端路径中的符号链接的方法是使用 --keep-dirlinks 选项,但这个选项还会影响整个传输过程中的所有链接到目录的符号链接。

从早于 rsync v3.0.0 的版本中拉取文件时,如果发送端的路径字符串中的隐含路径内有符号链接,但想要在接收端将这些符号链接处理成普通目录,那么需要使用这个选项。

--backup, -b

如果目标路径中存在需要被传输或被删除的文件,那么就重命名这些预先存在的文件。可以使用 --backup-dir--suffix 选项来指定这些要被重命名的文件要被放在什么创房,以及在重命名这些文件时要给它们加上怎样的后缀。

如果不指定 --backup-dir 参数:

  1. --omit-dir-times 选项被强制使用
  2. 使用 --delete (不使用 --delete-excluded) 会导致 rsync 添加一个起保护作用的筛选规则到已经存在的所有过滤器后面,例如 -f "p *~" 。这个规则保护了前面被重命名的文件不被删除。

注意,如果使用了自己定义的筛选规则,可能需要手动插入自己的 exclude/include 规则,并且保证其优先级较高防止被其他规则先匹配上而导致失效。

--backup-dir=DIR

这个选项隐含了 --backup 选项,在接收端让 rsync 将所有要被备份的文件存储到指定的目录下。这个可以被用于增量备份。可以使用 --suffix 选项来指定要被备份的文件的新文件名的后缀。否则在备份目录中,被备份的文件的文件名不会改变。

注意,如果 DIR 指定了一个相对路径,那么 DIR 是相对于 DEST 中的路径字符串的相对路径。如果 rsync daemon 是接收端,备份目录无法在 rsync 模块指定的路径外被创建,这一点需要特别小心。

--suffix=SUFFIX

在使用 --backup 选项时,该选项可以用来指定默认的,备份文件的文件名的后缀。如果没有指定 --backup-dir 选项的话,默认的后缀是 ~ ;如果指定了 --backup-dir 选项的话,默认为空。

译者注: rsync 默认在被更新的文件的同级目录下新建一个临时文件,然后用这个临时文件覆盖要被更新的文件。这个临时文件的默认文件名就是要被覆盖的文件的文件名后面加一个 --suffix 指定的符号。

--update, -u

这个选项让 rsync 跳过 DEST 中已经存在的、修改时间比 SRC 中的源文件迟的文件。如果 DEST 上已经存在修改时间与 SRC 中的源文件相等,但大小不同的文件的话,DEST 中的文件会被更新为 SRC 中的源文件。

注意,该选项不会影响软链接或其他特殊文件的拷贝机制。而且,不管发送端和接收端的对象的时间是什么,总会考虑发送端和接收端上不同的文件格式。换句话说,如果源文件是一个目录,而 DEST 上已有一个同名的普通文件,则 rsync 会直接忽略它们的时间戳。

译者注: 文档的作者没写清楚。

译者注: 源文件是一个目录,DEST 上有一个和源文件这个目录同名的普通文件。那么,即使 DEST 上这个普通文件的日期更加新,DEST 上的和源文件这个目录同名的普通文件也会被删除,然后源文件这个目录会被传输过来。

译者注: 也就是说,源文件是一个目录的话,会被强制传输到 DEST 上。但源文件是一个文件的话,就符谁新谁留下的规则了。

这个选项是一个 TRANSFER RULE 传输规则 所以不受任何 exclude 规则的影响。

同时使用 --inplace--update 时需要小心: 传输过程被打断会导致接收端只接收了文件的一部分 (译者注: 尽管只是一部分,但这个没有接收完成的文件依旧和发送端源文件有相同的文件名) ,这个没有传输完成的文件的修改日期是最近的 (译者注: 文件传完后才会更新修改日期,但传输被打断,所以此时文件的修改日期是 rsync 把最后一个文件块写入文件的日期) ,所以重新运行 rsync 启动传输过程时,这个文件可能不会被更新。

--inplace

这个选项改变了 rsync 传输文件的模式,当文件需要被更新时,rsync 会直接向目标文件写入数据。而 rsync 默认的传输模式是,将数据保存在 DEST 中的临时文件中,待文件传输完毕后,将这个临时文件移动到目标地点并重命名。

这个传输模式有几个影响:

  • 硬链接不会被打破。这意味着新的数据可以通过其他地方的硬链接被访问。此外,尝试将不同的源文件复制到链接到同一 inode 的多个硬链接目标文件上,将导致目标数据来回变化的“拉锯战”。
  • 正在使用的二进制文件无法被更新。 (要么操作系统会保护正在使用的二进制文件,要么被更新的二进制文件对应的程序出现异常或崩溃)
  • 文件数据在传输过程中会变得在接收端与发送端不一致,如果 rsync 传输过程被打断或者更新失败,那么这个不一致状态会一直持续下去。
  • rsync 没有写权限的文件无法被更新。尽管管理员可以更新任何文件,但普通用户需要文件的写权限才能打开文件并向文件成功写入数据。
  • 如果目标文件中的数据在被复制到某个位置之前被覆盖,则 rsync 增量拷贝算法的效率会降低。如果使用了 --backup 选项则不会出现这样的问题,因为 rsync 足够智能,它会使用备份文件作为传输的基准文件。

警告: 当有其他程序使用文件时,不应当使用 --inplace 更新在被使用的文件。

这个选项在传输基于块的大文件,或者向 DEST 中的目标文件追加数据时很有用。也适用于那些基于磁盘的,而非网络的操作系统。它还可以防止支持支持 COW 功能的文件系统快照与仅有微小更改的文件的整个内容产生分歧。

译者注: 下面所有的译者注都在解释上一段的最后一句话。

译者注: 支持 copy-on-write 的文件系统的每个快照只包含文件系统的变化部分 (变化了的 block),以节省磁盘空间。现在,一个文件 f 在原始快照 A 后有了微小的更改,比如在文件末尾添加了几个 block 的数据 d。

译者注: 使用 --inplace 选项的 rsync 会直接操作已有的文件 f,只添加 f 变动的部分 d,不会让文件系统认为 f 被删除过。此时再做一个快照 B,那么 A B 两个快照的区别是,B 快照中只有文件 f 改变的部分 d。

译者注: 而不使用 --inplace 的 rsync (默认不使用) 的做法是建立一个新文件 f1,然后用新文件 f1 覆盖旧文件 f。这会让文件系统认为 f 被删除。此时再做一个快照 B,那么 A B 两个快照的区别是,B 中有删除 f 的一条记录和新文件 f1。其中,用来标识文件 f 被删除的记录占据的空间较少,但是新文件 f1 是从 f 复制所有数据再加上新的改变 d 而来。这导致 B 快照要存储整个文件 f + 改变的部分 d,出现了额外的空间开销。

译者注: 从上面的两个例子可以看出,比起使用 --inplace 选项时 rsync 的行为,rsync 的默认行为导致支持 copy-on-write 的文件系统除了要存储 f 改变的部分 d 之外,还要多存储一份文件 f。

译者注: 回到前提,如果对于文件 f 的更改是删除了几个 block。那么使用 --inplace 的情况下,快照 B 里面会记录有哪些块被删除。而 rsync 的默认行为会让快照 B 里面存储除了被删除的几个 block 之外的,文件 f 的所有 block。

这个选项还隐含了 --partial 选项 (因为传输被打断时不会删除正在传输的文件),但是这个选项与 --partial-dir--delay-updates 冲突。在 rsync v2.6.4 之前 --inplace 也与 --compare-dest--link-dest 不兼容。

--append

使得 rsync 以追加数据到文件尾部的方式来更新文件,它会假定接收端上已存在的文件和发送端文件的前段数据是一致的。如果不能确定文件只会以在文件尾部追加数据的方式变大,使用这个选项很危险。应当使用筛选规则来剔除不符合条件的文件。

这个选项隐含了 --inplace 选项,只更新体积增长的文件,并且不在接收端和发送端校验已有数据是否相同 (只校验增量数据是否正确传输)。rsync 跳过所有存在于接收端的,并且文件大小大于等于发送端对应文件的文件。同时,如果发送端的文件在传输过程中变小,rsync会发出警告,并跳过传输该文件。

当文件不需要传输时,rsync 仍然可以更新文件的非内容属性,例如更改文件的权限或所有权。同时,这种操作不会影响目录以及普通文件之外的文件的更新。

--append-verify

这个选项与 --append 相似,不同点在于,rsync 会校验所有的已经存在的数据 (降低传输效率但是更加安全)。如果不能确定文件只会以在文件尾部追加数据的方式变大,使用这个选项很危险。阅读 --append 选项的描述获取更多信息。

注意: 在 rsync v3.0.0 之前, --append 选项的工作模式类似于 --append-verify ,所以如果使用 v3.0.0 以上版本的 rsync 与 v3.0.0 以下版本的 rsync 交互 (也可以是版本号小于 30 的 rsync protocol),那么不论指定 --append 还是 --append-verify ,rsync 都会以 --append-verify 的模式工作。

译者注: 如果校验失败,即,两个文件的前半段不同。那么就使用普通的 --inplace 模式传输文件。

--dirs, -d

让发送端发送遇到的所有目录。与 --recursive 选项不同,目录的内容不会被拷贝,除非 SRC 的路径字符串中指定目录时使用了 "." 或者以一个斜杠结尾 (比如 ".", "dir/.", "dir/")。如果不指定这个选项与 --recursive 选项,rsync 会跳过遇到的所有目录 (并且输出目录不被传输的信息)。如果同时指定了 --dirs--recursive 两个选项,那么后者的优先级更高,即开始递归复制。

--dirs 在不指定 --recursive 时被 files-from 或者 --list-only 隐含。如果此时不使用这个选项,指定 --no-dirs 或者 --no-d

也有一个向后兼容的帮助选项 --old-dirs (--old-d)。这个选项告诉 rsync 使用 -r --exclude='/*/*' 选项来让旧版本的 rsync 以非递归的方式列出单一的目录。

译者注: 如果 SRC 中的路径字符串指向一个目录,那么这个目录会被传输到 DEST 上。如果 SRC 中的路径字符串指向了一个文件,那么此时使用 --dirs 没有意义,不影响 rsync 把这个文件传输到 DEST 上的默认行为。

译者注: 使用 "." "dir." 和 "dir/" 可以让 rsync 传输目录下的内容,包括子目录和文件。不创建父目录,不递归。/

译者注: 这个选项在只需要同步目录的属性时很有用。想不出其他的使用环境。

--mkpath

在 DEST 上创建 DEST 指定的路径字符串中不存在的路径。

默认情况下,rsync 只允许 DEST 指定的路径字符串中的最后一个部分不存在 (译者注: 比如 <dest>:/d1/d11/d111 中,rsync 默认只允许 d111 不存在) ,这是为了帮助用户验证目标路径是否存在。使用这个选项,rsync 会创建所有不存在的路径,就像在 DEST 主机上直接运行 mkdir -p <DEST-path-string> 的行为一样。

如果 DEST 的路径字符串以斜杠结尾,那么整个路径字符串都按目录路径来处理,即使 SRC 的路径字符串指向的是一个文件。可以查看 拷贝后使用不同的名字 一节来了解在什么情况下 DEST 的路径字符串会被指向一个文件或者目录。

译者注: 就是说,在使用这个选项时,如果 DEST 的路径字符串以斜杠结尾,那么就在 DEST 主机上创建整个路径对应的目录,然后把 SRC 路径字符串指定的文件拷贝到这个目录下。如果不以斜杠结尾的话,如果 SRC 的路径字符串指向了一个文件,那么 DEST 路径字符串的最后一部分就是这个文件在 DEST 上的名字。比如 rsync -vi --mkpath /tmp/file /tmp/dir1/dir11/ 将会出现文件 /tmp/dir1/dir11/file,而 rsync -vi --mkpath /tmp/file /tmp/dir1/dir11 将会出现文件 /tmp/dir/dir11 (注意 dir11 是个文件)。

如果想要让在 DEST 上创建的目录结构完全符合发送端使用的路径字符串,那应该使用 --relative (-R) 而不是这个选项。比如,下面两个命令可以在 DEST 上创建同样地目录树,但是只有第二个命令可以确保 "some/extra/path" 匹配发送端的目录:

rsync -ai --mkpath host:some/extra/path/*.c some/extra/path
rsync -aiR         host:some/extra/path/*.c ./

译者注: 上面这段话最后一句,只有第二个命令可以确保在接收端创建的目录可以匹配发送端的目录的意思是,只有使用第二个命令创建创建目录时,rsync 才会去同步发送端对应目录的权限。而 --mkpath 创建的目录可能不会匹配发送端对应目录的权限。

--links, -l

添加遇到的所有符号链接到传输列表,而不是忽略符号链接并产生一条 "non-regulat file" 的警告 (这个警告可以通过使用 --info=noreg0 选项屏蔽)。

默认的处理符号链接的方式是在接收端重新创建每个符号链接,并不改变符号链接链接到的地址。 译者注: 遇到符号链接时,在接收端重新创建符号链接。即拷贝符号链接本身

符号链接 一节说明了处理符号链接的方式。

--copy-links, -L

发送端传输每个遇到的符号链接的最终目标。如果符号链接的目标不存在,那么会显示一个错误并且取消传输这个文件。 译者注: 报错,并取消传输该符号链接。

这个选项取代了所有其他在传输中影响符号链接的选项。因为使用这个选项后,传输列表里就不存在符号链接了。

这个选项不改变接收端对已有符号链接的处理方式。rsync v2.6.3 之前的版本会告诉接收端也要遵循符号链接。rsync v2.6.7 之后,这个选项不会被发送到接收端 (发送端知道哪些符号链接要被解引用、解引用到哪就够了)。

译者注: 上面那段的第一句其实是想说 v2.6.3 之前版本的 rsync 执行 rsync -avi -L ... 的效果等于 v2.6.3 及之后版本的 rsync -avi -L --keep-dirlinks 即两者的不同是 --keep-disrlinks

译者注: 不改变接收端对已有符号链接的处理方式,这句话主要针对的接收端的路径内有可能会改变 SRC 的目录结构的符号链接的情况。比如在有如下目录的情况下将 save1 中的内容递归地复制到 save2 目录中。

# tree
.
├── save1
│   └── d1
│       ├── 11
│       └── d11
│           └── d111
└── save2
    ├── d1
    │   └── d11 -> ../tt
    └── tt

译者注: 这两条命令会产生一样的结果

rsync -avi -L save1/ save2
rsync -avi    save1/ save2
$ tree
.
├── save1
│   └── d1
│       ├── 11
│       └── d11
│           └── d111
└── save2
    ├── d1
    │   ├── 11
    │   └── d11
    │       └── d111
    └── tt

如果需要把接收端上链接到目录的符号链接作为普通目录处理,查看 --keep-dirlinks (-K) 选项。

符号链接 一节说明了处理符号链接的方式。

--copy-unsafe-links

让 rsync 复制指向 SRC 指定的路径之外的符号链接的引用。使用绝对路径的符号链接也被视为普通文件,使用 --relative 选项时,SRC 指定的路径中本身中的任何符号链接也是如此。/译者注: 注意,会对链接解引用。/

注意,判断链接是否 safe 的标准是,这个符号链接的目标是否在 SRC 路径字符串的最后一个斜杠之前所指的目录之内 (注意 SRC 的路径字符串末尾是否加斜杠)。另外,不论链接指向哪里,使用绝对路径的链接都算 unsafe。

给个例子,如果将 /src1/src11/subdir 复制到 /dest,那么 /src1/src11 是判断链接是否 safe 的节点。如果符号链接的目标在 /src1/src11 之内,那么这个链接被判定为 safe;如果符号链接的目标在 /src1/src11 目录之外,那么链接被判定为 unsafe。

但如果将 /src1/src11/subdir/(注意多了个斜杠) 复制到 /dest,那么 /src1/src11/subdir 才是判断链接是否 safe 的节点。如果符号链接的目标在 /src1/src11/subdir 之内,那么这个链接被判定为 safe;如果符号链接目标在 /src1/src11/subdir 之外,那么这个链接被判定为 unsafe。

注意,只有显式指定或者隐含了 --links 选项时才会复制安全符号链接。同时使用 --copy-unsafe-links--copy-links 选项时,选项 --copy-unsafe-links 没有额外的效果。

译者注: 作者想说的是,选项 --safe-links 不隐含 --links--safe-links 只是对 --links 的限制;选项 --copy-unsafe-links--copy-links 隐含;选项 --safe-links 不隐含 --copy-links

符号链接 一节说明了处理符号链接的方式。

--safe-links

让 rsync 忽略链接到 SRC 路径字符串根节点之外的符号链接。忽略使用绝对路径的链接。 注意: 不对链接解引用,这个选项只是对 --links 的限制。

因为这个筛选链接的过程只发生在发送端,所以即使发送端 munge 要发送的符号链接 (使用 --munge-links),这个选项仍然有效。它也会影响接收端的删除行为,因为当符号链接被认为不安全并被发送端跳过时,如果接收端存在与被跳过的符号链接同名的文件,那么这个同名文件不会被删除。

这个选项必须与 --links (或 --archive) 选项一起使用以便有条件地忽略传输中的任何符号链接。它的效果被 --copy-unsafe-links 抑制。 译者注: 这段读不懂就去读 --copy-unsafe-links 选项的解释吧。这段描述确实不好读懂。

将此选项与 --relative 结合使用可能会产生不被期望的结果。

符号链接 一节说明了处理符号链接的方式。

--munge-links

让 rsync 在接收时 munge 链接的指向,并在发送时 unmunge 链接的指向。链接指向被改变导致连接无法使用,但是该选项还可以恢复符号链接的原始指向。

server 侧的 rsync 通常在 client 不知情的情况下启用此选项,例如在 rsync daemon 的配置文件中配置,或通过 rrsync (restricted rsync) 脚本提供的选项配置。如果 client 需要 munge 从 remote 接收的符号链接,则通常指定该选项;或者 server 需要 munged 从 remote 接收符号链接时使用 -M--munge-links 将选项提供给 server。请注意,在本地传输中,client 是发送端,因此直接指定该选项会 unmunge 符号链接,而将其指定为远程选项则会 munge 符号链接。

译者注: 本地侧是 client,远程侧是 server。需要注意的是,发送端使用这个选项的效果是 unmunge 链接,接收端使用这个选项的效果是 munge 链接,然后上面那段话就好理解了

将这个选项通过 --remote-option 发送到 rsync daemon 不影响 daemon 的行为,因为 rsync daemon 只通过 munge symlinks 配置参数来决定是否 munge 链接。

译者注: 后面的内容除了绝大部分是我自己改过的,还调整了顺序。

rsync munge 链接的做法是给链接添加 "rysncd-munged" 前缀,这意味着只要这个目录不存在链接就不能使用。使用这个选项时,如果 /rysncd-munged 路径存在,那么 rsync 拒绝运行 (尽管它仅在启动时检查)。另请参阅源代码支持目录中的 "munge-symlinks" python 脚本,了解就地 munge/unmunge 一个或多个符号链接的方法。

译者注: 这个选项的作用是修改链接指向的地址。比如 remote-SRC 上有一个软链接 link@ -> a.c 拷贝到 localhost 后软链接变成了 link@ -> /rsyncd-munged/a.c。使用 --munge-links 将 link@ -> /rsyncd-munged/a.c 传到其他的 remote-DEST,这个链接又变回了 link@ -> a.c。

一旦符号链接开始传输,就会被 munged/unmunged,因此,任何将符号链接转换为非符号链接的选项都会在 munging/unmunging 之前发生。但 --safe-links 这个选项影响的是接收端的判断。当接收端收到被 munge 了的链接,这些链接以 "rsyncd-munged" 开头,第一个字符是斜杠,会被接收端判定为绝对路径,所以这些被 munge 了的链接都不会被接收端创建。当接收端接收到的是被 unmunge 的链接,那么原链接中的 "rsyncd-munged" 会被去掉,恢复成正常链接,此时接收端就按照正常的 --safe-links 判定逻辑来决定是否创建链接。

--copy-dirlinks, -k

这个选项让发送端将链接到目录的符号链接解引用,就像这个符号链接是一个真正的目录一样。这个选项不影响链接到非目录文件的符号链接, --copy-links 可以同时影响链接到目录的符号链接与链接到非目录的符号链接。

不使用这个选项时,如果发送端用一个链接到目录的同名符号链接替换了目录,那么接收端会删除妨碍创建对应的新符号链接的内容 (译者注: 即,如果接收端上有和发送端的符号链接同名的目录,那么这个目录会被删除,以在接收端创建与被删除目录同名的符号链接) (只要 --force-delete--delete 有效)。

接收端有一个相似功能的 --keep-dirlinks 选项。 译者注: 这个选项让接收端的,链接到目录的符号链接像一个真正的目录一样。

--copy-dirlinks 适用于 SRC 中的所有指向目录的符号链接。如果只想针对几个指定的符号链接解引用,则可以将它们作为带有尾部斜杠的 SRC 参数传递,通过 --relative 使路径正确匹配。比如:

rsync -r --relative src/./ src/./follow-me/ dest/

译者注: follow-me 是指向目录的符号链接。

rsync 按给出的顺序在所有的 SRC 路径上调用 lstat(2),第二个 SRC 参数的路径字符串尾部的斜杠让 lstat(2) 可以查看符号链接的目标目录下的信息,从而产生一个对应的文件列表。而后产生的文件列表又会覆盖先产生的文件列表: 后产生的以 follow-me 为根的文件列表覆盖了第一个 SRC 参数生成的传输列表中的 follow-me 符号链接。这样做也能有对某个特定符号链接解引用的效果。

符号链接 一节说明了处理符号链接的方式。

--keep-dirlinks, -K

如果发送端的一个目录在接收端对应位置有一个同名的、指向目录的符号链接,就让接收端的,这个链接到目录的符号链接像一个真正的目录一样地被使用。如果不使用这个选项,那么接收端的,与发送端对应目录同名的符号链接会被删除,并在同样位置创建一个同名的真正的目录。

比如,要传输一个 foo 目录,该目录下有一个 file 文件,但接收端上的 foo 是一个到 bar 目录的符号链接。不使用这个选项时,接收端会删除符号链接 foo,重新创建一个名为 foo 目录,然后接收 file 文件到这个新建的 foo 目录下。如果使用这个选项,那么 file 文件最终会被接收端保存在 bar 目录下。

需要小心: 如果使用 --keep-dirlinks 那就必须信任接收端已经存在的所有符号链接,或者在接收端启用 --mungle-links 选项。如果不受信任的用户可以创建自己的指向任何真实目录的符号链接,则用户可以在后续副本中将该符号链接替换为真实目录,并影响符号链接引用的任何目录的内容。对于备份来说,最好使用 bind mount 之类的功能而不是符号链接来修改接收目录的层次结构。

发送端有一个相似功能的 --copy-dirlinks 选项。 译者注: 这个选项让发送端的,链接到目录的符号链解引用。

符号链接 一节说明了处理符号链接的方式。

--hard-links, -H

让 rsync 在 SRC 中查找具有硬链接的文件并将它们再在 DEST 上链接在一起。如果不使用此选项,SRC 中的硬链接将被视为单独的文件。

这个选项不保证 DEST 上的硬链接数量精确匹配 SRC 中的硬链接。DEST 可能会出现额外的硬链接的情况有:

  • 如果 DEST 包含比 SRC 中对应文件的硬链接数量更多的硬链接 (比源文件列表中存在的链接更多),复制算法不会显式破坏它们。然而,如果 SRC 和 DEST 的链接有内容差异,文件更新过程将破坏这些额外的链接 (除非您使用 --inplace 选项)。 译者注: 使用 --inplace 选项不会破坏硬链接的对应关系,但是可能会破坏硬链接的文件的内容。
  • 如果指定了一个包含有硬链接的 --link-dest 目录,那么接收目录中的文件有可能会与 --link-dest 指定的目录中的硬链接链接在一起,从而可能导致接收目录中的本没有链接关系的文件链接在一起。

译者注: 给个例子解释第一点在说什么。

# 两个 file1 完全相同
 SRC: file1, link2(to file1), link3(to file1)
DEST: file1, link4(to file1), link5(to file1)

rsync -avi --hard-links SRC DEST

 SRC: file1, link3(to file1), link4(to file1)
DEST: file1, link2 link3 link4 link5 (all to file1)

# --------

# 两个 file1 内容不同
 SRC: file1(new), link2(to new file1), link3(to new file1)
DEST: file1(old), link4(to old file1), link5(to old file1)

# 注意,没有用 --inplace,默认策略是创建新文件,再用新文件覆盖旧文件
rsync -avi --hard-links SRC DEST

 SRC: file1(new), link2(to new file1), link3(to new file1)
DEST: file1(new), link2(to new file1), link3(to new file1),
                  link4(to old file1), link5(to old file1)

# --------

# 两个 file1 内容不同
 SRC: file1(new), link2(to new file1), link3(to new file1)
DEST: file1(old), link4(to old file1), link5(to old file1)

# 用 --inplace 直接修改 DEST 上已有的文件
rsync -avi --hard-links --inplace SRC DEST

 SRC: file1(new), link2(to new file1), link3(to new file1)
DEST: file1(new), link2 link3 link4 link5 (all to new file1)

译者注: 给个例子解释第二点在说什么。但是在看这个例子前应该先了解 --compare-dest, --copy-dest--link-dest 是什么意思。现在 --link-dest 指定了一个 DIR,这个 DIR 中有文件 file1 与其硬链接 file2,以及一个独立的文件 file3。现在 SRC 指定的目录下有与 DIR 中的 file1, file2 同名、同内容且同属性的文件 file1, file2,但 SRC 中的 file1 和 file2 不是硬链接关系,file2 和 file4 是硬链接关系。那么 rsync -avi --link-dest=DIR --hard-links SRC DEST 执行完之后,DEST 中本不应该具有链接关系的 file1 和 file4 有了链接关系:

DIR: file3 file1 <-> file2
SRC:       file1     file2 <-> file4

rsync -avi --link-dest=DIR --hard-links SRC DEST

DIR:  file3 file1 <-> file2
              |         |
DEST:       file1     file2 <-> file4

注意,rsync 只会检索要传输的文件之间的硬链接关系。如果 rsync 在接收端更新了一个硬链接到 DEST 指定路径之外的文件,则接收端上的这个硬链接关系会被破坏。使用 --inplace 选项可以避免破坏链接到路径之外的硬链接。(有关更多注意事项,参阅 --inplace 选项)。

译者注: rsync 更新文件的默认策略是新建一个文件,然后用新文件覆盖旧文件,这样一覆盖,硬链接就没了,所以这个硬链接就被破坏了。使用 --inplace 的话,rsync 会直接更改这个与发送端文件同名的硬链接,也就不会破坏硬链接关系了。但后果就是,硬链接文件的内容会被修改。

如果使用了增量递归功能 (--inc-recursive),接收端的 rsync 可能会在找到有硬链接的文件的其他硬链接之前,先传输这个文件。这不影响传输的准确性 (不影响哪些文件被链接在一起),只是影响性能。增量递归的目的是尽快开始传输文件,这意味着,如果 rsync 使用 "quick check" 算法判定这个文件需要被传输,那么 rsync 会立即将其传输到接收目录,不会马上检查这个要被传输的文件是否存在其他的硬链接关系。这可能导致 rsync 传输了本可以使用硬链接避免传输的文件,而且这个硬链接关系可能在一段时间之后才能被建立,这样降低了性能。避免这个问题的方式是使用 --no-inc-recursive 选项来避免使用增量递归。

--perms, -p

让接收端为传输的文件设置与发送端一样的权限。(--chmod 选项可以修改发送端发往接收端的文件的权限。即,让权限应用于接收端,而不影响发送端。)

当不使用这个选项时,权限这样设定:

  • 接收端已有文件权限不变。(但 --executability 选项可能改变文件的执行权限)
  • 新文件从发送端获取普通权限值,再配合接收端文件所在目录的 ACL 权限或 umask 值决定文件的最终权限,并且会禁用被传输来的文件的特殊权限位,除非新的目录文件从其父目录中继承了 sgid 权限。

因此,当 --perms--executability 都被禁用,rsync 的行为于文件拷贝工具 (比如 cp 和 tar) 的行为相同。

总结: 要给接收端的文件 (已有文件和新文件) 与发送端一样的权限,使用 --perms 。要让接收端接收的文件使用接收端默认的权限 (已有文件权限不动),禁用 --perms 并且使用 --chmod=ugo=rwX (这个选项保证了所有非掩码位的权限都被启用)。想让后一种情况输入起来更容易,可以定义一个 popt 别名,例如将下面的命令行放入文件 $HOME/.popt 中 (命令定义了 -Z 选项,并使用了 --no-g 使得接收端接收的文件的所属组使用接收端目录的默认组):

rsync alias -Z --no-p --no-g --chmod=ugo=rwX

译者注: chmod 使用大写 X 的意思是,如果操作的是个目录,就给这个目录的 ugo 都加上 x;如果操作的是个文件,一旦文件的 ugo 其中之一有 x 权限,那么就给这个文件的 ugo 都加上 x 权限。

可以使用 popt 文件中定义的新选项,像这样:

rsync -avZ src/ dest/

警告: 请确保 -a 选项在 -Z 前,否则 -Z 定义的 --no-p--nog-g 选项会失效 (被 -a 隐含选项覆盖)。

rsync v2.6.7 添加了在关闭 --perms 选项的情况下,保留接收端新建目录的 sgid 的功能。当 --perms 关闭时,较旧的 rsync 版本错误地保留了新创建文件的三个特殊权限位,同时覆盖了接收端新创建目录上的 setgid 位。默认要遵守 ACL 的配置已添加到 rsync v2.6.7 的 ACL 补丁中,因此即使存在默认 ACL,较旧的 (或未启用 ACL 的) rsync 也会使用 umask。请记住,受影响的是接收端的 rsync,接收端的不同版本对应不同的行为。

--executability, -E

使得 rsync 在未指定 --perms 选项时,在接收端保留普通文件的执行权限。文件的 ugo 之一设置了 x 就认为这个文件可执行。当文件已在接收端存在,且和发送端的对应文件的可执行权限值不一样时,rsync 将这样修改接收端文件的权限:

  • 让文件可执行。如果接收端文件的 u, g, o 中有 r 权限,那么 rsync 就打开对应 u, g, o 的 x 权限
    • 比如,发送端权限 rwxrw-rw-,接收端文件权限 r---w----,最终接收端文件权限是 r-x-w----
  • 让文件不可执行。如果发送端文件的 u, g, o 没有 x 权限,那么 rsync 就取消 u, g, o 对应的 x 权限
    • 比如,发送端权限 rw-r--r--,接收端文件权限 rwx-w---x,最终接收端文件权限是 rw--w----

如果指定了 --perms 选项,则该选项被忽略。

--acls, -A

更新接收端文件的 ACL 属性使之和发送端对应文件的 ACL 属性一致。该选项隐含了 --perms 选项。

发送端和接收端的系统中必须使用互相兼容的 ACL 实体。如果不兼容,选项 --fake-super 可以备份带有 ACL 属性的文件并恢复带有 ACL 属性的文件。

--xattrs, -X

更新接收端文件的扩展属性使之和发送端对应文件的扩展属性一致。

对于支持扩展属性 namespace 的系统来说,管理员用户的 copy 行为复制了除 system.* 之外的所有的 namespace。普通用户的 copy 行为只复制 user.* namespace。为了让普通用户可以备份与恢复 non-user namespace 的属性,查看 --fake-user 选项。

可以通过 X 修饰符使用一个或多个过滤器选项来覆盖上面的 name filter。在指定影响 xattr 的过滤规则时,rsync 要求用户做自己的 system/user 过滤,以及对要复制的 xattr name 的任何其他过滤,以及允许删除哪些 name。例如,要跳过 system namespace,可以指定:

--filter='-x system.*'

要跳过除 user namespace 的所有 namespace,需要指定 user namespace 取反的匹配:

--filter='-x! user.*'

要保护所有的属性不被删除,需要指定接收端特有的规则来排除所有的 name:

--filter='-xr *'

注意, -X 选项没有复制 rsync 的特殊 xattr 值 (比如那些被 --fake-super 选项使用的值),除非用户使用 -XX 。这个表示复制所有 xattr 属性的 -XX 不能和 --fake-super 一起用。

--fileflags

这个选项让 rsync 更新接收端的 file-flags 与发送端的文件和目录相同 (如果系统支持 chflags(2) 系统调用的话)。有些 flag 只能由管理员修改,有些 flag 只能在某个安全级别 (通常是单用户模式) 以下清空设置 (unset)。如果接收端的文件被设置为不可修改 (immutable),rsync 不会让这些文件变得可修改 (alterable)。但可以使用 --force-change, --force-uchange--force-schange 选项让不可修改的文件变得可修改。

--force-change

让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 user-immutable 和 system-immutable 标志 (让 user 和 system 的相关选项变得可修改)。这个选项覆盖了 --force-uchange--force-schange

--force-uchange

让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 user-immutable 标志 (让 user 的相关选项变得可修改)。这个选项覆盖了 --force-change--force-schange

--force-schange

让 rsync 在接收端上正在被更新或删除的文件和目录上禁用 system-immutable 标志 (让 system 的相关选项变得可修改)。这个选项覆盖了 --force-change--force-uchange

--chmod=CHMOD

让 rsync 在传输时应用一个或多个逗号分隔的 chmod 模式到要被传输的文件。让 rsync 以为这些指定的权限就是发送端文件的权限。也因此在未配合 --perms 使用时该选项无效。

chmod(1) 的 man page 中记录了普通的语法解析规则,可以通过加上一个前缀 D 来指定该权限规则只对目录有效,或者加上前缀 F 指定该权限规则只对普通文件有效。例如,下面的例子保证了所有目录都标记了 sgid 权限,所有者和所属组都可写,其它人对文件都不可写,且所有人都有执行权限:

--chmod=Dg+s,ug+w,Fo-w,+X

也允许使用八进制值模式:

--chmod=D2775,F664

也允许使用多次该选项,每个选项的值都会被附加到权限操作列表中。 译者注: 意思是后面的值会覆盖前面的值。

如何将生成的权限值应用于传输中的文件,参阅 --perms--executability 选项。

--owner, -o

让 rsync 将接收端文件的所有者设置为和源文件一样,但要求接收端的 rsync 以 super user 身份运行 (见 --super--fake-super 选项)。如果不指定该选项,接收端已有文件和新文件的所有者将设置为接收端调用 rsync 的用户身份。

默认情况下,接收端文件的属主的用户名需要与发送端的用户名匹配,但在某些环境下,可能会使用 uid。(详见 --numeric-ids 选项)

--group, -g

让 rsync 将接收端文件的属组设置为和源文件一样,但要求接收端的 rsync 以 super user 身份运行 (见 --super--fake-super 选项)。如果不指定该选项,接收端已有文件和新文件的属组将设置为接收端调用 rsync 的属组身份。

默认情况下,接收端文件的属组的组名需要与发送端的组名匹配,但在某些环境下,可能会使用 uid。(详见 --numeric-ids 选项)

--devices

让 rsync 可以传输 character device 和 block device 到接收端上,以在接收端重新创建这些设备。该选项要求接收端 rsync 以 super-user 身份运行,否则接收端的 rsync 遇到这些 device 就直接跳过。(见 --super--fake-super 选项)

默认情况下,rsync 在不指定这个选项时,遇到每一个 device file 都会生成 "non-regular file" 警告。可以使用 --info=nonreg0 让 rsync 不显示这个警告。

--specials

让 rsync 传输特殊文件,比如 named socket, fifo。如果接收端的 rsync 没有以 super-user 身份启动,rsync 就不会传输特殊文件。(见 --super--fake-super 选项)

让 rsync 可以传输 character device 和 block device 到接收端上,以在接收端重新创建这些设备。该选项要求接收端 rsync 以 super-user 身份运行,否则接收端的 rsync 遇到这些 device 就直接跳过。(见 --super--fake-super 选项)

-D

等于 --devides --specials 一起用。

--copy-devices

让发送端的 rsync 按照常规文件来处理 device,允许将 device 内容拷贝到接收端的普通文件中 (如果使用了 --write-devices 选项,也可以拷贝到其他的设备中)。

译者注: --copy-devices 允许从 device 中读, --write-devices 允许向 device 写。

这个选项不能被 rsync daemon 使用。

--write-devices

让接收端的 rsync 按照常规文件来处理 device,允许将文件数据写入 device 中。

这个选项隐含了 --inplace 选项。

用这个选项的时候要小心,用户应该知道出现 DEST 路径字符串中的设备是什么,特别是以 root 身份运行 rsync 时。

译者注: --copy-devices 允许从 device 中读, --write-devices 允许向 device 写。

这个选项不能被 rsync daemon 使用。

--times, -t

让 rsync 将 mtime 随文件一起传输给 receiver,使得目标文件的 mtime 和源文件一样。注意,如果不使用这个选项,原本通过排除 mtime 相同的文件而获得的性能提升将不再生效;换句话说,如果没有使用 -t-a 将导致下一次传输以类似于使用 --ignore-times (-I) 选项的方式进行,即更新所有文件。尽管在文件没有真正发生更改的情况下,rsync 的增量传输算法可以让更新效率很高,但最好还是使用 -t 选项让计算量更小些。

使用 transfer protocol 30 或者 31 的现代 rsync 使用 8 字节来传输 mtime。如果 rsync 被强制与旧的 rsync protocol 通信 (可能由于接收端的 rsync 版本小于 3.0),那么 mtime 会使用 4 字节来传输。在 v3.2.7 之前,4 字节可以传输 1901.12.13 到 2038.01.19 范围的日期。从 v3.2.7 开始,4 字节可以传输 1970.01.01 到 2106.02.07 范围的日期。如果文件所需要的时间早于 1970 年,要确保 rsync 可执行文件已升级以便可以传输全范围的日期。

--atimes, -U

让 rsync 将 atime 随文件一起传输给 receiver,使得目标文件的 atime 和源文件一样。

重复使用的效果等同于使用 --open-noatime 选项,这让接收端收到的文件拥有与发送端文件相同的 atime,而不必在传输完成后额外运行一次 rsync。

需要注意,小于 v3.2.0 的 rsync 可能使用了 pre-release patch,这种情况下重复使用该选项并不会等同于使用 --open-noatime 选项。

--open-noatime

如果系统支持的话,让 rsync 以 O_NOATIME flag 打开文件以避免改变要被传输的文件的 atime。如果系统不支持 O_NOATIME flag 则 rsync 会忽略该选项,并且不产生提示。也要注意,有些文件系统被挂载时指定了不更新文件 atime 的选项,这种情况下,rsync 不论使用不使用该选项,文件的 atime 都不会被改变。

--crtimes, -N

让 rsync 在接收端收到的文件上设置与发送端相同的 ctime。

--omit-dir-times, -O

让 rsync 在保留文件 mtime, atime 和 ctime 时,忽略目录的这些属性。如果接收端正通过 NFS 共享该目录,推荐使用该选项。若指定了 --backup 但是没有指定 --backup-dir 则隐含了该选项。

这个选项有一个副作用是,可以避免在启用增量递归时过早创建缺失的子目录,如 --inc-recursive 部分中所述的那样。

--omit-link-times, -J

让 rsync 在保留文件 mtime, atime 和 ctime 时,忽略符号链接的这些属性。

--superr

让接收端尝试 super-user 的行为,即使接收端的 rsync 并不是以 super-user 的身份启动的。这些行为包括: 通过使用 --owner 保留文件所有者,通过使用 --groups 保留文件所属组 (包括辅助组),通过使用 --devices 选项拷贝 device。在接收端没有以 super-user 身份启动 rsync 时,这些选项很有用。如果要禁用这些 super-user 行为,使用 --no-super 选项。

--fake-super

让 rsync 根据需要,通过附加到每个文件的特殊扩展属性来保存/恢复特权属性,从而模拟 super-user 行为。扩展属性包括:文件的 owner, group,文件的设备信息 (device 文件和特殊文件被创建为空文本文件),以及不被允许在真正文件上设置的 (比如,真正的文件为了安全性有设置 u-s, g-s, o-t),或者那些会限制所有者的访问的 (因为正真的 super-user 总是可以访问/改变文件,被创建的文件总是可以被创建者访问/改变),所有的权限位。如果和 --acls 选项一起用的话,这个可以让 rsync 处理 ACL 属性,如果和 --xattrs 一起用的话,可以让 rsync 处理非用户的扩展属性。

这这选项,可以在不使用 super-user 的情况下备份数据,并存储来自不兼容系统的 ACL。

这个选项只影响使用了这个选项的一侧。要影响另一端的 rsync,需要使用 --remote-option (-M) 选项:

rsync -av -M--fake-super /src/ host:/dest/

对于本地拷贝来说,这个选项同时影响发送端和接收端。如果在本地拷贝中,只让接收端受该选项的影响,需要指定 -M--fake-super ;只让发送端受该选项影响,需要使用 --fake-super -M--super

这个选项覆盖了 --super--no-super

可以查看 rsync daemon 的 rsyncd.conf 文件中 fake super 的设置。

--sparse, -S

让 rsync 尝试高效地处理稀疏文件,让他们在接收端可以占用更小的空间。如果与 --inplace 一起使用,那么在某些内核版本和/或文件系统的组合下,创建的文件可能最终不会以稀疏块结束。 译者注: 似乎作者是想说,在某些内核版本与文件系统的组合下, --sparse --inplace 可能会导致接收端最终创建的不是一个稀疏文件。 可以与 --whole-file 一起用 (比如在本地拷贝中),因为 rsync 在把文件更新到最新版本之前会先创建稀疏文件。

译者注: 注意 v3.2.7 中 --inplace --sparse 一起用有 bug,v3.3.0 才修,详见此链接

注意,版本号小于 v3.1.3 的 rsync 会拒绝同时使用 --sparse--inplace

--preallocate

让接收端的 rsync 在每一个文件传输前预先分配空间。rsync 只会使用 Linux fallocate(2) 系统调用和 Cygwin 的 posix_fallocate(3) 提供的文件系统级别的预分配功能,而不是向每一个 block 写 null 的慢速 glibc 实现。

不使用这个选项时,大文件可能在文件系统中不连续,但使用这个选项会让 rsync 的拷贝速度变慢。如果接收端没有使用 extent filesystem (例如 ext4、xfs、NTFS 等),则此选项可能根本没有任何积极作用。

--sparse 结合使用时,如果内核版本和文件系统支持在分配的数据中创建 hole,则文件将仅具有稀疏块 (而不被分配的空字节序列)。

--dry-run, -n

让 rsync 模拟运行,而不改变任何数据,并且产生像 rsync 真正运行时那样的输出。多数时候它与 --verbose (-v) 与/或 --itemize-changes (-i) 一起使用,在真正执行 rsync 命令前确定命令如何运行。

--itemize-changes 的输出在模拟运行和随后的实际运行中应该完全相同 (除非故意欺骗和系统调用失败);如果不是,那就表示 rsync 有 bug。其他输出应该大部分不变,但在某些方面可能有所不同。值得注意的是,模拟运行不会发送文件传输的实际数据,因此 --progress 没有效果,"bytes sent", "bytes received", "literal data" 和 "matched data" 统计数据太小,并且 "speedup" 值相当于不需要传输文件时的运行情况。

--whole-file, -W

禁用 rsync 的增量传输功能,让 rsync 传输整个文件的所有数据。如果发送端和接收端的网络带宽高于接收端到硬盘的带宽 (特别是硬盘是一个网络文件系统时),该选项可以加快传输速度。当接收端与发送端都在本地,而且没有使用 batch-writing 选项时,默认使用这个选项。

--no-whole-file, --no-W

在本地传输时,默认会启用 --whole-file ,这个选项在本地传输时禁用 --whole-file 选项。这通常会让 rsync 变慢,但在想要让写操作最小化时 (要与 --inplace 一起用),或者测试基于校验和的增量传输算法时,这个选项很有用。

--checksum-choice=STR, --cc=STR

STR 指定的算法覆盖了默认的 checksum 算法。如果 STR 指定了一个 checksum 算法的名字,那么发送端和接收端都会在传输前和传输时使用这个算法 (假设两端都用了 --checksum 选项)。如果 STR 指定了两个算法的名字,这两个算法名使用逗号分隔,那么第一个算法名被用于传输文件时,第二个算法名被用于传输文件前 (-c)。

checksum 算法可以使用这些值:

  • auto (默认,自动选择算法)
  • xxh128
  • xxh3
  • xxh64 (也叫 xxhash)
  • md5
  • md4
  • sha1
  • none

执行 rsync --version 可以看到默认被编译进 rsync 的 checksum 列表 (可能与上面的列表不同)。

如果使用 none 作为逗号分隔的两个算法名的第一个,或者只使用 none 作为选项的值,那么 --whole-file 会被强制使用,并且在文件传输之后不会有计算 checksum 值并比对的步骤。如果 none 作为第二个值,或者作为唯一值,则不能使用 --checksum 选项。

auto 是选项的默认值,rsync 选择的算法基于客户端和服务器之间的协商,如下所示:

当两端的版本都至少是 v3.2.0 时,rsync 选择 client 的算法列表中的第一个也同时出现在 server 算法列表中的算法。如果没有这样的算法,rsync 报错退出。如果 remote rsync 太老而不支持 checksum 协商,那么算法基于 protocol 版本选择 (根据 protocol 版本在 MD5 和多个基于 MD4 的算法间选择)。

可以在环境变量 RSYNC_CHECKSUM_LIST 中自定义默认的算法顺序,每个算法名用空格隔开。如果算法名包含 "&" 字符,则将其分为 "client string & server string",否则同一字符串适用于两者。如果变量值 (或值的某部分) 不包含非空字符 译者注: 作者是想说值为空。 ,则使用默认的算法列表。此方法不允许将传输时使用的算法和与传输前使用的算法分开指定,并且它会忽略 auto 和所有未列出的算法名称。仅包含无效名称的列表会导致协商失败。

译者注: 如果环境变量的值中出现 "&" 字符,则表示 "&" 前的算法名为 client 使用的算法列表,"&" 后的为 server 使用的算法列表。如果环境变量的值中没有出现 "&" 字符则表示该列表同时适用于 client 和 sever。

使用 --checksum-choice 选项会覆盖这个环境变量列表。

--one-file-sytem, -x

让 rsync 不跨文件系统递归。该选项不会限制用户从多个文件系统指定 SRC,仅限制了 rsync 在每个目录下的递归行为,同时也以类似的方式限制接收端删除数据时的递归行为。需要记住,使用 mount 命令的 "bind" 了 device 时,device 被认为是在同一个文件系统上。

译者注: 例如 mnt 目录常用来做挂载点,则递归根目录时,mnt 目录内的数据不会被扫描。

如果重复指定该选项,rsync 将忽略 client 所有的挂载点目录。否则,遇到挂载点时将它们当作是空目录 (这些空目录使用已挂载目录的属性,因为挂载点目录的原始属性无法访问)。

如果指定了 --copy-links--copy-unsafe-links 选项使得 rsync 展开符号链接,那么如果符号链接所指向的是另一个设备上的目录,那么该符号链接按挂载点处理。该选项不会影响指向非目录的符号链接。

--ignore-non-existing, --existing

让 rsync 不创建接收端不存在的文件与目录。如果这个选项与 --ignore-existing 选项一起使用,则不会更新任何文件 (这在用户只想要删除无关文件而不想要更新已有文件时很有用)。

这个选项是一个 TRANSFER RULE,所以不会被任何 exclude 规则影响。

--ignore-existing

让 rsync 不更新已经在接收端上的文件。但会传输接收端没有的文件,已有的目录也会被更新。见 --ignore-non-existing 选项。

译者注: 不论用户使用什么选项都不更新已有文件,但如果用户使用了 -ptgo 这些选项,则 rsync 依旧可以更新已有目录的属性。

这个选项是一个 TRANSFER RULE,所以不会被任何 exclude 规则影响。

译者注: 下面这段的前提是用户没有用 --inplace 选项。

使用 --link-dest 选项做备份时,碰巧备份被中断,如果想继续完成备份,则该选项有用。因为 --link-dest 选项会拷贝到一个新的目录层次中,使用 --ignore-existing 将保证已存在的文件不会被调整。这意味着该选项仅关注接收端已存在的文件。

使用 --info=skip2 时,rsync 将输出 "FILENAME exists (INFO)" 消息,其中INFO 表示 "type change", "sum change" (需要 -c 选项), "file change" (基于 quick check), "attr change", "uptodate" 之一 。使用 --info=skip1 (也由 -vv 选项隐含) 输出不带 INFO 后缀的存在消息。

--remove-source-files

让 rsync 在将文件传输到接收端之后,删除发送端的对应文件 (不删目录)。

注意,发送端传输的文件应当是在传输过程中不被写入的文件。如果要将特定目录中的文件移到另一台主机上,要确保已做好传输准备的文件被重命名到发送端指定的 SRC 目录中,而不是将要被传输的文件直接写入发送端指定的 SRC 目录,这样 rsync 就不可能传输尚未写入完成的文件。如果不能首先将文件写入不同的目录,则应该使用命名习惯用法,使 rsync 避免传输尚未完成的文件(例如,在写入文件时将其命名为“foo.new”,在完成后将其重命名为“foo”,然后使用选项 --exclude='*.new' 开始传输)。

自 v3.1.0 开始,如果文件大小或 mtime 改变,rsync 将不会删除发送端的对应文件,并输出 error。 译者注: 我猜,作者想说的是,文件传输开始时记录一下 mtime,传输完后看一下 mtime 变了没有。如果变了,不删文件,报错;如果没变,正常删文件,走下个流程。

从 3.2.6 开始,本地 rsync 副本将确保发送端不会删除接收端刚刚验证过的文件。比如,用户将源目录和目标目录设为相同路径时。

--delete

让 rsync 删除接收端的多余文件 (指没有在发送端出现过的文件),但只对那些被同步的目录生效。用户必须要求 rsync 发送整个目录 (写法是 "dir" 或者 "dir/") 而不是对目录内容使用通配符 (比如 "dir/*")。因为通配符被 shell 解析成独立的文件名,而不被解析成这些文件的所在目录。被排除在传输列表之外的文件也被排除在删除列表之外,除非使用 --delete-exclude 选项或者将规则标记为仅在发送端匹配 (见 过滤规则 一节的 include/exclude modifier)。

在早于 v2.6.7 的版本中,除非使用 --recursive 否则这个选项没有影响。自 v2.6.7 开始,当使用 --dirs (-d) 选项时,这个选项也生效,但只对那些要被同步的目录生效。

这个选项如果用错了就很危险!在运行使用了这个选项的 rsync 命令前,先使用 --dry-run 命令查看哪些文件要被删除。

如果发送端检测到了 I/O error,那么就不再删除任何文件。这样做的目的是在文件系统出现临时异常时 (比如 NFS error) 不会在发送端大量删除文件。用户可以使用 --ignore-errors 来禁用这个遇到 I/O error 就不再删任何文件的行为 (让 rsync 继续删除)。

这个选项可以与 --delete-WHEN 选项一起用而不会有冲突,包括 --delete-excluded 选项。然而,如果不指定 --delete-WHEN 选项,当 rsync 的对端版本在 v3.0.0 及以上时会选择 --delete-during ,当对端版本在 v3.0.0 以下时会选择 --delete-before 选项。更多信息见 --delete-delay--delete-after 选项。

--delete-before

让 rsync 在传输开始前先删除接收端对应的文件。这个选项隐含了 --delete 选项。更多关于文件删除方式的信息见 --delete 选项。

在传输开始前先删除文件的行为对于那些文件系统空间紧张的接收端很有用。然而,这个行为引入了从命令执行到文件开始传输之间的额外的延迟,如果指定了 --timeout 选项的话,这可能导致传输超时。这也强制 rsync 使用旧的非增量递归的算法,让 rsync 一次性扫描所有的文件到内存中 (见 --recursive)。

--delete-during, --del

让 rsync 在传输期间增量地删除接收端的文件。在检查接收端目录内要被更新的内容前,先扫描那些要被删除的文件,在开始更新文件之前删除要被删除的文件。所以这个选项的行为像更高效的 --delete-before 选项。这个选项自 v2.6.4 被首次加入。这个选项隐含了 --delete 选项。更多关于文件删除方式的信息见 --delete 选项。

译者注: rsync 扫到一个目录,先过滤出要被删除的文件,然后过滤出要被更新的文件;在更新要被更新的文件之前,删除要被删除的文件。配合增量递归算法,实现每扫一个目录就删除这个目录下要被删除的文件的目的。

--delete-delay

让 rsync 在传输期间计算要在接收端被删除的文件 (与 --delete-during 类似),然后在传输完成后删除要被删除的文件。这在与 --delay-updates 和/或 --fuzzy 同时使用时很有用,并且比 --delete-after 更高效 (但与 --delete-after 选项的行为不同,因为 --delete-after 会在所有传输完成之后再一次性计算要被删除的文件)。如果要被删除的文件使得 rsync 内部的缓存溢出,那么接收端的 rsync 会创建一个临时文件来储存那些要被删除的文件的名称 (该文件在读取时被删除,所以用户不应在传输过程中看到这个文件)。如果不能创建临时文件,rsync 会尝试回落到 --delete-after 选项 (译者注: 即在传输全部完成后才删除文件) 。这个选项隐含了 --delete 选项。更多关于文件删除方式的信息见 --delete 选项。

译者注: --delete-delay 在传输过程中删文件,在增量递归中,先传完要传的文件,再删除不需要的文件,然后递归下一个目录。 --delete-after 在传输全部结束之后才删除文件。

--delete-after

让 rsync 在所有传输都完成后,再删除文件。如果用户想要把使用 per-directory merge 方式的规则文件作为文件传输的一部分,并且希望它们的排除规则在当前传输的删除阶段生效,则此功能非常有用。它还强制 rsync 使用旧的非增量递归算法,该算法要求 rsync 将传输中的所有文件一次扫描到内存中 (见 --recursive)。

如果用户只是想要让删除操作发生在数据传输之后的话,可以参考效率更高的 --delete-delay 选项。

--delete-excluded

此选项将任何 unqualified exclude/include 规则转换为不影响接收端删除行为的 server 端规则。

译者注: 这个选项告诉 rsync 即使文件在发送端被 --exclude 排除了,也要在接收端将其删除。

默认情况下,exclude/include 规则在 server 端 (可以在构建 server 端文件列表时隐藏和显示文件) 和接收端 (在删除文件的阶段保护文件) 都有效。如果没有 modifier 来指定这个规则要在哪一端生效,规则默认在 server 端生效。

即使使用了这个选项,如果规则同时使用了发送端和接收端的规则修饰符 (比如 -f'-sr foo' ),规则依旧可以被应用于两端。接收端的规则也可以被指明来限制删除。这使用户不必将一堆 -f'-foo' 规则编辑为 -f'-s foo' (又名 -f'H foo') 规则 (更不用说相应的 include 规则)。

过滤规则 一节有更多的信息。这个选项隐含了 --delete 选项。更多关于文件删除方式的信息见 --delete 选项。

--ignore-missing-args

当 rsync 第一次处理明确被请求的发送端文件 (例如命令行参数或 --files-from 实体) 时,如果找不到文件,通常会出现错误。此选项会抑制该错误,并且不尝试传输该文件。如果最初发现某个文件存在,但后来不再存在,则该选项不会影响随后的 vanished-file 错误。

--delete-missing-args

这个选项隐含了 --ignore-missing-args 选项,但比它做得更多: 每一个未在发送端找到的参数都会变成一个接收端对应文件的删除请求。如果接收端的文件是一个非空目录,那么这个非空目录在指定了 --force-delete 或者 --delete 的选项的情况下会被删除。此外,这个选项独立于其他的各种删除过程之外。

不存在的发送端文件由特殊的文件列表条目表示,这些条目在 --list-only 输出中显示为 "*missing" 条目。

--ignore-errors

让使用了 --delete 的 rsync 即使遇到 I/O 异常也继续删除文件。

--force-delete, --force

如果接收端的非空目录与发送端的文件同名,删除接收端的非空目录。只有在未使用 --delete 时,该选项才起作用 (见 --delete 选项)。

注意,一些较旧的 rsync 版本在使用 --delete-after 时需要 --force ,并且除非同时启用 --recursive 选项,否则这个选项不起作用。

--max-delete=NUM

让 rsync 不要删除超过 NUM 数量的文件或目录。如果删除的文件或目录的数量等于 NUM,那么后续的删除操作都被跳过。最后,rsync 输出一条警警告 (警告内容包括被跳过的删除操作的总数) 并且以错误代码 25 结束运行 (如果有比这更严重的错误,错误码会换成更严重的错误的错误码)。

自 v3.0.0 开始,用户可以指定 --max-delete=0 来查看最后的警告中显示的删除文件的数量而不删除它们。老的 client 不能使用这个参数,所以如果用户不知道目前的 rsync 是什么版本,可以使用 --max-delete=-1 作为向后兼容的方式来告诉 rsync 不要删除文件 (虽然非常老的 rsync 在要删除的文件数量超过 NUM 时不会输出警告)。

--max-size=SIZE

让 rsync 不传输任何大小大于 SIZE 的文件。数值可以带有字符串后缀以表示单位,或者不加后缀单位表示以字节计算。可随意使用小数值和单位,例如 --max-size=1.5m。

这个选项是一个 TRANSFER RULE,所以不会被任何 exclude 规则影响。

单位字符串的第一个字母可以是 B (bytes), K (kilo), M (mega), G (giga), T (tera) 或者 P (peta)。如果单位只使用一个字符,或者使用 "ib" 结尾 (比如 "G" 或者 "GiB") 那么单位是 1024 的倍数。如果单位字符串使用了两个字符,并且使用 "B" 结尾 (比如 "kb") 那么单位是 1000 的倍数。字符串中的字符可以是大小写混合或者纯小写,使用哪个都行。

最后,如果字符串使用 "+1" 或者 "-1" 结尾,那么这表示向特定方向加一或者减一个字节。最大的,可能的值通常是 8192P-1

比如: --max-size=1.5mb-1 是 1499999 字节, --max-size=2g+1 是 2147483649 字节。

注意,小于 v3.1.0 版本的 rsync 不允许 --max-size=0

--min-size=SIZE

让 rsync 不传输小于 SIZE 大小的文件。SIZE 的取值和写法参考 --max-size 选项。

注意,小于 v3.1.0 版本的 rsync 不允许 --min-size=0

--max-alloc=SIZE

默认情况下,rsync 将单个 malloc/realloc 的大小限制在 1GB 左右。对于大多数人来说,这个限制工作得很好,它可以防止协议错误导致 rsync 请求大量内存。但是,如果一次传输中有数百万个文件,接收端有大量内存可用,并且不想将传输分成多个部分,则可以将每次分配内存的限制设置一个更大的值,rsync 将消耗更多的内存。

记住,这个选项并不是在限制分配给 rsync 的总内存大小。这是在每次内存分配时的安全性检查的值。

--max-size 选项描述了限制要传输的文件的大小的方式。

自 v3.2.3 开始,SIZE 值取 0 表示不设限制。

用户可以用环境变量 RSYNC_MAX_ALLOC 设置该选项的默认值,该环境变量的值与 SIZE 有相同的含义与写法。如果 remote rsync 不支持 --max-alloc 选项,用户可以使用 --max-alloc=1g 来覆盖环境变量的值,这样 rsync 就不会向 remote rsync 发送 --max-alloc 选项 (因为 1G 是默认值)。

译者注: 环境变量可以设置该选项的默认值,但是如果环境变量的 SIZE 值不是 1G,那么 --max-alloc 会被发送给 remote rsync。如果 remote rsync 不支持这个选项,可以在 local rsync 上用 --max-alloc=1g 让这个选项的值回归默认,local rsync 检测到默认值没有被改变就不会向 remote rsycn 发送 --max-alloc 选项。

--block-size=SIZE, -B

强制 rsync 在增量传输时使用 SIZE 指定的 block size。它通常是根据正在更新的每个文件的大小来选择的。详见技术报告。

译者注: 技术报告 technical report 我没找见在哪。

自 v3.2.3 开始,SIZE 可以使用 --max-size 选项中描述的那种格式。老版本的 rsync 只能使用纯数字 (以 byte 为单位),不能带后缀。

--rsh=COMMAND, -e

允许用户选择 local rsync 与 remote rsync copies 交互要使用的 remote shell。典型地,rsync 被配置默认使用 ssh,但用户可以在本地网络中使用 rsh。

如果这个选项以 [user@]host::module/path 格式使用,那么 remote shell COMMAND 会被用于在 remote 主机上运行 rsync daemon,并且所有数据会被通过这个 remote shell 传输,而不是直接通过 remote 主机上正在运行的 rsync daemon 的 socket 连接传输。见 通过 remote shell 连接使用 rsync-daemon 一节。

自 v3.2.0 开始,在通过 remote shell 创建 daemon 连接时,环境变量 RSYNC_PORT 环境变量会被设置。如果 rsync daemon 使用默认的端口号,该环境变量的值为 0,否则该环境变量的值会被设置为 --port 指定的值,或者是 rsync:// URL 中使用的值。这允许脚本辨别是否请求了非默认端口,从而允许 SSL 或 stunnel 辅助脚本等连接到默认端口或备用端口。

如果 COMMAND 作为单个参数提供给 rsync,那么 COMMAND 中允许使用命令行参数。用户必须使用空格 (不能是 TAB 或者其他的 whitespace) 分隔命令和参数,而且可以使用单引号和/或双引号来保证参数内的空格被正常解析 (不能用反斜杠转义)。注意,被单引号引起来的字符串中如果还需要引号,则可以使用双引号;被双引号引起来的字符串中如果还需要引号,则可以使用单引号。一些例子:

-e 'ssh -p 2234'
-e 'ssh -o "ProxyCommand nohup sh firewall nc -w1 %h %p"'

(注意,ssh 用户可以通过 .ssh/config 文件针对不同站点使用不同的配置)

用户还可以通过 RSYNC_RSH 环境变量来选择 remote shell 程序,环境变量的值与该选项的值相同。

--blocing-io 选项受这个选项的影响。

--rsync-path=PROGRAM

这个选项指定了在 remote 主机上用哪个命令来启动 rsync。多数时候被用于 rsync 不在 remote-shell PATH 指定的路径中的情况 (比如 --rsync-path/usr/local/bin/rsync)。注意,PROGRAM 由 shell 执行,所以 PROGRAM 可以是用户想要运行的任何程序、脚本、或者命令序列,只要他不破坏被用于 rsync 交互的标准输入/输出。

一个棘手的例子是在远程机器上设置一个不同的默认目录,以便与 --relative 选项一起使用。比如:

rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/

--remote-option=OPTION, -M

用于更高级的情况,即用户希望某些选项仅在传输的一侧生效。比如,想要在 remote 主机的 rsync 中使用 --log-file=FILE--fake-super 选项,这样写:

rsync -av -M --log-file=foo -M--fake-super src/ dest

如果用户想让在两侧生效的 rsync 选项只在 local 主机生效,向 remote 主机发送关闭选项的指令即可。像这样写:

rsync -av -x -M--no-x src/ dest/

使用这个选项时要小心,因为切换选项可能导致 rsync 对 socket 上的下一个数据有不同的想法,这将使传输以一种神秘的方式失败。

注意, -M 参数一次只能传递一个选项,多个选项需要使用多次该选项。在旧版的 rsync 中,OPTION 中的任何空格都可能导致它被拆分为单独的 remote arg,但这需要在现代 rsync 中使用 --old-args

译者注: 上面那段话我从第二句开始就读不懂了。

在进行本地传输时,local 侧是发送端,remote 侧是接收端。

注意有些 rsync 版本上 popt 选项解析库有 bug,这个 bug 会会阻止用户在短选项字母旁边使用带有等号的相邻参数 (例如 -M--log-file=/tmp/foo)。如果出现该问题,用户可以使用 rsync 附带的 popt 版本。

--cvs-exclude, -C

这是一种有用的简写方式,可以排除用户通常不希望在系统之间传输的各种文件。它使用与 CVS 类似的算法来确定是否应忽略文件。

exclude list 被初始为化为不包含以下项目 (这些初始项目被标记为 perishable,参阅 过滤规则 部分):

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
.nse_depinfo *~  #* .#* ,* _$* *$ *.old *.bak *.BAK *.orig
*.rej .del-* *.a *.olb *.o *.obj *.so *.exe *.Z *.elc *.ln
core .svn/ .git/ .hg/ .bzr/

然后,被 $HOME/.cvsignore 文件中列出的文件,以及任何在环境变量 CVSIGNORE 中列出的文件都被添加到列表中 (所有 cvsignore 项目以空格为界)。

最后,如果任何文件与 .cvsignore 文件位于同一目录中,并且与其中列出的模式之一匹配,则会忽略该文件。与 rsync 的 filter/exclude 文件不同,这些匹配模式以空格为分界。有关更多信息,见 cvs(1) 手册。

如果 -C 与用户自己的 --filter 规则结合在一起,应该注意,无论 -C 放在命令行的什么位置,这些 CVS 排除都会附加在用户规则的末尾。这使得它们的优先级低于用户明确指定的任何规则。如果想控制这些 CVS 排除在哪里被插入到用户的过滤规则中,应该省略 -C 选项,并使用组合选项 --filter=:C --filter=-C (或者在命令行上,或者通过将 ":C" 和 "-C" 规则与其他规则一起放入筛选器文件中)。第一个选项打开 .cvsignore 文件的按目录扫描。第二个选项一次性导入如上所述的 CVS excludes。

--filter=RULE, -f

允许用户添加规则以有选择地从要传输的文件列表中排除某些文件。这与递归传输结合使用时最有用。

可以在命令行上使用任意数量的 --filter 选项来构建要排除的文件列表。如果过滤器包含空格,将过滤器用引号包起来,以便 shell 将规则作为单个参数提供给 rsync。下面的文本还提到您可以使用下划线来替换空格,将规则与其参数分隔开的空格。

过滤规则 一节有更多的信息。

-F

是 --filter 规则的简写。 -F 对应的规则是:

--filter='dir-merge /.rsync-filter'

这告诉 rsync 查找散布在层次结构中的每个目录的 .rsync-filter 文件,并使用它们的规则来过滤传输列表中的文件。 -FF 对应的规则是:

--filter='dir-merge /.rsync-filter' --filter='exclude .rsync-filter'

这会从传输中过滤掉 .rsync-filter 文件本身。

过滤规则 一节有更多的信息。

--exclude=PATTERN

--filter 选项的简化版,它指定了一个排除规则,并且它不解析普通的筛选规则。这个选项等于 -f'- PATTERN'

过滤规则 一节有更多的信息。

--exclude-from=FILE

--exclude 选项有关,但它指定的是一个包含 exclude 规则的文件 (每行一个 exclude 规则)。空行被忽略;以 ;# 开始的行是注释,也被忽略 (包含这些字符的文件名不受影响)。

如果行以 '- ' (短横线,空格) 或者 '+ ' (加号,空格) 开始,那么规则的类型被显式地指定为 exclude (前者) 或 include (后者)。任何没有此类前缀的规则都被视为 exclude 规则。

如果行只由 '!' 构成,那么当前的过滤规则在添加后续的其他规则之前被清除。

如果 FILE 是 '-' (短横线),那么就从标准输入中读取列表。

--include=PATTERN

--filter 选项的简化版,它指定了一个包含规则,并且它不解析普通的筛选规则。这个选项等于 -f'+ PATTERN'

过滤规则 一节有更多的信息。

--include-from=FILE

--exclude 选项有关,但它指定的是一个包含 include 规则的文件 (每行一个 include 规则)。空行被忽略;以 ;# 开始的行是注释,也被忽略 (包含这些字符的文件名不受影响)。

如果行以 '- ' (短横线,空格) 或者 '+ ' (加号,空格) 开始,那么规则的类型被显式地指定为 exclude (前者) 或 include (后者)。任何没有此类前缀的规则都被视为 include 规则。

如果行只由 '!' 构成,那么当前的过滤规则在添加后续的其他规则之前被清除。

如果 FILE 是 '-' (短横线),那么就从标准输入中读取列表。

--files-from=FILE

允许用户指定要被传输的文件的精确列表 (从文件中读取列表或使用 '-' 从标准输入读取列表)。它还调整了 rsync 的默认行为,以便更轻松地仅传输指定的文件和目录:

  • 隐含 --relative (-R) 选项,这个选项保留了 FILE 中每个条目的路径信息。使用 --no-relative--no-R 可以关闭这个选项。
  • 隐含 --dirs (-D) 选项,这个选项在接收端创建文件列表中的目录,而不是跳过目录。使用 --no-dirs 或者 --no-d 可以关闭这个选项。
  • 选项 --archive (-a) 隐含的 --recursive 失效,如果需要这个选项需要手动指定 --recursive 一次。
  • 这些副作用会更改 rsync 的默认状态,因此命令行上 --files-from 选项的位置与其他选项的解析方式无关。例如 -a 写在 --files-from 之前或之后没有区别, --no-R 和所有其他选项也是如此。

从 FILE 中读取的文件名都相对于 SRC 中指定的目录。任何前导斜杠都会被删除,并且不允许使用 ".." 引用 SRC 中指定的目录值钱了的目录。例如,以下命令:

rsync -a --files-from/tmp/foo /usr remote:/backup

如果 tmp/foo 文件中包含字符串 "bin" (或者甚至 "/bin"),那么 /usr/bin 目录会在接收端被创建为 /backup/bin。如果包含 "bin" (注意尾部斜杠),那么目录下一级的内容也会被传输 (自 v2.6.4 开始不需要显式指定,下一级的内容默认被传输)。在这两种情况中,如果使用了 -r 选项,那么目录的整个结构都会被传输。要记得,在使用 --files-from 选项时必须显式指定 -r 。因为在使用 --files-from 选项时,选项 -a 中的 -r 参数不起作用。另外,请注意,使用 -r 选项的作用是,仅复制从文件中读取的目录的完整结构,而不是复制 SRC 指定的路径 (在本例中为 /usr) 的完整结构。

此外,如果在 FILE 前面指定 "host:" (主机必须与传输的一端匹配),则可以从远程主机而不是本地主机读取 FILE 文件。作为快捷方式,用户可以仅指定前缀 ":" 来表示 remote 主机。比如,下面的命令让 rsync 从 src 主机中取到 /path/file-list 文件,并依据此文件指定的文件列表复制 SRC 主机 / 目录下的内容:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

译者注: --files-from 从 remote 主机取 FILE 的写法是 [[user@]host:] 。重点在于,两个 HOST 字符串必须完全匹配,或者只简写 --files-from 的 HOST 字符串:

# OK
rsync -a --files-from=fbsd:/tmp/file /tmp/copy fbsd:/tmp/path

# NO
rsync -a --files-from=root@fbsd:/tmp/file /tmp/copy fbsd:/tmp/path
rsync -a --files-from=fbsd:/tmp/file /tmp/copy root@fbsd:/tmp/path

# OK
rsync -a --files-from=root@fbsd:/tmp/file /tmp/copy root@fbsd:/tmp/path

如果使用了 --iconv--secluded-args 选项并且 FILE 从一台主机发送到另一台主机,则 FILE 指定的文件将从发送端的字符集转换为接收端的字符集。

注意: 对 --files-from 指定文件中包含的文件列表进行排序有助于 rsync 更加高效,因为这可以让 rsync 避免重复访问相邻条目之间共享的路径元素。如果输入未排序,某些路径元素 (隐含的目录) 可能会被多次扫描,并且 rsync 最终会在它们变成发送端内部的文件列表之后取消这种重复扫描。 译者注: 发送端会自己维护一个文件列表,这个文件列表是排过序的。

--from0, -0

让 rsync 从文件中读取规则或文件名时以空字符 (\0) 终止。该选项会影响 --exclude-from, --include-from, --files-from 以及所有在 --filter 中指定的规则合并文件。它不会影响 --cvs-exclude (因为从 .cvsignore 文件中读取的名称都是以空白字符分隔的)。

译者注: 可以简单理解成,原来是一行一个,现在可以把多行写成一行,用空格分隔。

--old-args

让 rsync 不保护 remote 端的 arg 值不受意外分词或其他误解的影响。它还允许 client 将空参数视为 ".",而不出现错误。

现代 rsync 中默认将发送到 remote shell 的参数中的,影响 shell 行为的字符 (包括空格) 使用反斜杠转义。通配符 *,?, [, &, ] 出现文件名参数中则不被转义 (允许它们被 shell 扩展为多个文件名),而在选项参数 (如 --usermap) 中受到保护。

如果一个脚本想要在其文件名中使用旧式参数分割,请指定此选项一次。如果 remote shell 存在任何反斜杠转义问题,请指定此选项两次。

还可以通过 RSYNC_OLD_ARGS 环境变量控制此设置。 如果它的值为 "1",rsync 将默认为使用一次该选项。 如果它的值为 "2" 或更大,rsync 将默认为多次使用该选项。如果它是 "0",使用默认的转义行为。该环境变量的值总是被在命令行指定该选项,或者在命令行指定关闭该选项覆盖 (关闭该选项使用 --no-old-args)。

注意,此选项还会禁用 v3.2.5 中添加的额外安全检查,以确保 remote 发送端不会在文件列表中包含用户未请求的额外顶级条目。这种副作用是必要的,因为 rsync 无法确定远程 shell 解释参数时会出现什么名称。

这个选项与 --secluded-args 选项冲突。

--secluded-args, -s

通过 protocol (而不是 remote shell 命令行) 将所有文件名和大多数选项发送到远程 rsync,这样可以避免让 remote shell 修改这些数据。通配符被 rsync 扩展而不是 remote 主机上的 shell。

这类似于 v3.2.4 中添加的参数的默认反斜杠转义 (见 --old-args),因为它可以防止空格拆分和不需要的特殊字符副作用。然而,它的缺点是与 v3.0.0 之前的 rsync 不兼容,并且被希望能检查所有选项值以确保安全的受限的 shell 拒绝。

如果 remote shell 与默认的反斜杠转义方法不兼容,或者有其他原因希望大多数选项和参数绕过 remote shell 的命令行,则此选项在需要为远程主机转换参数的字符集时非常有用。

如果将此选项与 --iconv 结合使用,与 remote 端相关的参数将从本地字符集转换为远程字符集。转换发生在扩展通配符之前。见 --files-from 选项。

环境变量 RSYNC_PROTECT_ARGS 还可以控制启用或禁用该选项。如果它具有非零值,则默认情况下启用此设置,否则默认情况下禁用此设置。但如果用户在 rsync 命令中使用了启用该功能的 --secluded-args 选项,或禁用该功能的 --no-secluded-args 选项,那么该环境变量的值不生效。此环境变量的值也会被 RSYNC_OLD_ARGS 环境变量的非零值覆盖。

这个选项与 --old-args 选项冲突。

在 v3.2.6 之前,这选项被 --protect-args 调用,并且 --protect-args 目前依旧可以被使用。使用简写 -s 可以始终保持兼容性。

译者注: --protect-args 被改名成 --secluded-args ,但是他们的简写都是 -s

--trust-sender

禁用 local client 端对 remote 发送端生成的文件列表执行的两项额外验证检查。仅当用户相信发送端不会在文件列表中放入恶意内容 (可能通过修改的 rsync、修改的 shell 或其他类似操作来完成的操作) 时,才应使用此选项。

通常,当从 remote rsync 中接收文件时,rsync client (从 v3.2.5 开始) 会运行两次额外的验证:

  • 验证 rsync 命令没有使用额外的参数条目。
  • 验证传输列表中的任何条目都不是应被排除的内容 (如果使用了过滤规则的话)。

有些选项会干扰验证,这会导致两个验证过程中的某一个,或者全部的验证被跳过。比如:

  • 在从 remote rsync 接收文件时,在 remote 主机上为要被传输的每个目录使用单独的过滤文件,这样只有 remote rsync 知道过滤规则,因此 local rsync 的过滤规则验证被禁用。
  • --old-args 选项允许发送端操作请求的参数,因此 local rsync 的参数检查被禁用。
  • 从 server 端读取 --files-from 指定的列表文件意味着 client 端不知道参数列表,因此参数检查被禁用。 译者注: --files-from 指定的列表中包含的是 SRC 中的路径参数,这些路径参数是被 rsync 动态加载的,不是直接在命令里给的。rsync 只验证用户给的部分。用户没有给全参数,存在动态加载的部分,就不验证了。
  • --read-batch 会导致两个验证都被禁用,因为 batch file 的内容将在创建时得到验证。

如果额外的模式匹配会减慢大量传输的速度,则此选项可能会对功能不足的 client server 有所帮助。它还可用于解决来自可信发件人的传输验证逻辑中的当前未知的错误。

使用此选项时,最好指定一个专用 DEST 目录,如 多主机安全问题 一节所述。

--copy-as=USER[:GROUP]

让 rsync 使用 USER 和 GROUP (如果在冒号后指定了的话) 进行复制操作。只有当运行 rsync 的用户能够更改用户时,这才有效。如果未指定 GROUP,则使用被指定的用户的默认组。

此选项有助于降低 rsync 以 root 身份运行到可能发生实时更改的目录中或从可能发生实时更改的目录中的风险,并且用户希望 root-level 的对于系统文件的读写无法执行。虽然用户也可以指定某个用户来运行所有的 rsync 指令,但有时需要使用 root-level 的主机访问凭据,因此这允许 rsync 在 (使用 root 身份) 建立 remote shell 或 rsync daemon 连接后丢弃 root 身份使用该选项指定的身份。

如果所有复制操作都发生在本地,那么该选项影响发送端和接收端两侧;否则该选项只影响传输中的某一侧。该选项默认在 local 侧生效,使用 --remote-option 选项让该选项在 remote 侧生效,例如 -M--copy-as=joe 。对于本地传输,lsh (或 lsh.sh) 支持文件提供了一个 local shell 帮助脚本,该脚本可以被用于允许使用 "localhost:" 或 "lh:" 主机规范而无需设置任何 remote shell,该脚本允许指定作用于使用了这个主机规范的传输的一侧的 remote 选项 (使用主机名 "lh" 可以避免将远程目录覆盖到用户的主目录)。

译者注: 一般情况下,rsync 要先连接到 shell,之后才能切换 shell 的身份,然后用该身份的 shell 拉起一个 rsync 进程或者 rsync daemon,此时被拉起来的进程的身份就是选项指定的身份。回到上一段,简单理解,它说 rsync 源码目录下的 support/lsh.sh 这个脚本提供了一个功能,这个功能可以让需要切换身份的本地传输不必打开 shell。

比如,下面的 rsync 命令将本地文件以 joe 的身份写入:

sudo rsync -aiv --copy-as=joe host1:backup/joe/ /home/joe/

译者注: sudo 让 rsync 以 root 身份启动,那么连接到发送端主机 host1 使用的身份也是 root。 --copy-as 让接收端主机上的 rsync 以选项指定的身份启动,从而可以在接收端更改文件的所有权。

这使得所有文件都归用户 joe 所有,文件的属组被限制为 joe 的默认组 (因为并没有在选项中指定组名),并且 joe 用户无权修改 SRC 中的路径下的文件。

以下命令以用户 joe 的身份使用 local copy 复制到 dest/ 目录中 (假设 support/lsh 已被安装到 $PATH 指明的目录中):

sudo rsync -aive lsh -M--copy-as=joe src lh:dest/

--temp-dir=DIR, -T

让 rsync 在接收端创建对应文件的临时副本时使用 DIR 作为临时目录存储临时副本。不使用该选项的默认行为是,在与接收端对应文件同级的目录中创建每个临时文件。从 rsync v3.1.1 开始,DIR 内的临时文件的名称不会以额外的点为前缀 (尽管它们仍会添加随机后缀)。

当接收端的磁盘分区没有足够的可用空间来保存传输中最大的文件的副本时,最常使用此选项。当临时目录位于不同的磁盘分区上时,rsync 必须将临时文件复制到对应目标文件的位置。rsync 通过将文件覆盖到目标文件来实现该目的,这意味着目标文件在此复制过程中将包含 truncated data。不这样做的话,如果有用户打开了这个文件,旧文件可能会继续占用磁盘空间。即使首先删除目标文件,将数据本地复制到目标目录中的临时文件,然后重命名到对应位置也一样,被打开的文件依旧占用着磁盘空间。因此,磁盘上可能没有足够的空间容纳新版本。

如果出于磁盘空间不足以外的原因使用此选项,则用户可能希望将其与 --delay-updates 选项结合使用。接收端收到的文件先进 DIR,一个文件接收完后就马上从 DIR 被移动到 DEST 的各级目录的 .~tmp~ 目录中。使用 --delay-updates 选项让 rsync 创建了这个目录,在传输完全部文件之前,已经被传输了的各级文件都在各自所在目录中的 .~tmp~ 目录里。所有要被传输的文件都进入 .~tmp~ 目录后 (都进入,表示传完了),最后一次性把 .~tmp~ 目录中的文件重命名到对应位置。如果没有足够的空间来存储到达接收端目标分区上的文件 (就是没有足够的空间分给 .~tmp~ 目录),则告诉 rsync 不关心磁盘空间的另一种方法是使用带有相对路径的 --partial-dir 选项。这里相对路径的效果是,在文件的目标路径下创建同级目录,在这个同级目录下接收文件,收完之后从这个同级目录把文件重命名到它的目标地址。如果 --partial-dir 选项值使用绝对路径的话,就不会在文件的目标路径中创建临时目录,而是只使用指定的那个目录。

译者注: --delay-updates 已经解释清楚了。选项 --temp-dir--partial-dir 的区别在于前者不关心传输过程是否被打断;后者可以做到传输被打断以后下次可以继续传输,而不是删除已经传输了的部分,重新开始传输。除此之外,它们的行为完全一样。

--fuzzy, -y

让 rsync 为未找到的任何接收端的目标文件查找基础文件。当前算法在与目标文件相同的目录中查找大小和修改时间相同的文件,或名称相似的文件。如果找到,rsync 会使用这个基础文件来尝试加快传输速度。

如果重复使用这个选项,模糊扫描也将在 --compare-dest, --copy-dest--link-dest 指定的目录中完成。

注意,使用 --delete 选项可能会删除任何潜在的模糊匹配文件。要防止这种情况,使用 --delete-after 或指定一些文件名排除项。

--compare-dest=DIR

让 rsync 使用 DEST 上的 DIR 作为额外的层次结构。将 DIR 所包含的文件树作为基准与发送端要传输的内容比较。如果在 DIR 中发现了和发送端完全一致的文件,则该文件将不会被传输到 DEST 指定的目录中。该选项在做稀疏备份时很有用,因为它仅备份与某一次更早的备份相比发生了改变的文件。

自 v2.6.4 版本开始,可以使用多个 --compare-dest 选项让 rsync 根据指定的顺序做精确匹配。如果 DIR 中的文件和发送端要发送的文件内容相同、属性不同,那接收端就从 DIR 中拷贝文件到接收目录下,然后更改文件的属性。如果没有发现内容相同的文件,那就从 DIR 指定的目录中选取一个基准文件来加速从发送端到接收端的复制过程。 译者注: 这个基准文件一般是要被更新,但还没被更新的文件,即,只有在更新文件时才会有基准文件来加速传输过程。如果发送端要传输的文件是全新的 (没有同路径下的同名文件),那么就没有基准文件,传输就无法加速。

如果 DIR 是一个相对路径,那它是相对于 DEST 中的路径字符串的路径。还可以看 --copy-dest--link-dest

注意: 自 v3.1.0 开始,如果 rsync 在 compare-dest 目录中找到了精确匹配,那么就会从非空的 DEST 中删除对应的文件。(使 DEST 中保存的数据更接近一次全新的拷贝)

--copy-dest=DIR

--compare-dest 接近,但 rsync 会从接收端的 DIR 目录中以本地拷贝的方式拷贝未改变的文件到接收目录中。这在改变 DEST 的保存目录但是不想变更已经保存的数据时很有用。

可使用多个 --copy-dest 选项让 rsync 根据指定的顺序做精确匹配。如果没有发现完全匹配的文件,那就从 --copy-dest 指定的目录中选一个基准文件来加速从发送端到接收端的复制过程。 译者注: 这个基准文件一般是要被更新,但还没被更新的文件,即,只有在更新文件时才会有基准文件来加速传输过程。如果发送端要传输的文件是全新的 (没有同路径下的同名文件),那么就没有基准文件,传输就无法加速。

如果 DIR 是一个相对路径,那它是相对于 DEST 中的路径字符串的路径。还可以看 --compare-dest--link-dest

--link-dest=DIR

--copy-dest 接近,但未更改的文件会从 DIR 硬链接到接收目录。发送端要发送的文件的所有属性 (例如权限、所属) 必须与 DIR 中对应的文件相同,才能在 DEST 中创建到 DIR 中的硬链接。

如果 DIR 中的文件没有被硬链接到接收目录中,检查一下 DIR 中的文件和发送端的对应文件的属性是否相同。也要注意检查文件属性是否受 rsync 之外的程序控制,比如使用 mount 选项将 root 身份降为普通用户,或者使用通用权限挂载了一个可移动的存储设备 (比如 OS X 的 "Ignore ownership on this volume" 选项)。

自 v2.6.4 开始,可以使用多个 --link-dest 选项来指定多个精确检索的目录,rsync 会按顺序检索它们 (--link-dest 不能超过 20 个)。如果 DIR 中的文件和发送端要发送的文件内容相同、属性不同,那接收端就从 DIR 中拷贝文件到接收目录下,然后更改文件的属性。如果没有发现内容相同的文件,那就从 DIR 指定的目录中选取一个基准文件来加速从发送端到接收端的复制过程。 译者注: 这个基准文件一般是要被更新,但还没被更新的文件,即,只有在更新文件时才会有基准文件来加速传输过程。如果发送端要传输的文件是全新的 (没有同路径下的同名文件),那么就没有基准文件,传输就无法加速。

这个选项在接收文件到空的接收端目录时效果最好。假设,接收目录中已经存在一些文件时,rsync 要更新接收目录中已经存在的文件。如果接收目录中已经存在的文件是指向 DIR 中对应文件的硬链接,那么一旦接收目录中的文件被修改,DIR 中对应的文件也会被修改。此外,逐项列出更改可能会有点混乱。注意,在 v3.1.0 之前,当要传输的文件已经存在于接收目录时,rsync 就不会去 DIR 里找对应的文件 (即使 DIR 里有与发送端精确匹配的文件,rsync 也不会在接收目录里创建到 DIR 中对应文件的硬链接)。

注意,如果把 --link-dest--ignore-times 组合使用,rsync 不会创建任何文件的链接,因为 --link-dest 只是将相同的文件链接在一起,作为传输文件的替代,而不是作为在文件更新后的额外检查。

如果 DIR 是一个相对路径,那它是相对于 DEST 中的路径字符串的路径。还可以看 --compare-dest--copy-dest

注意,早于 v2.6.1 版本的 rsync 的 --link-dest 有一个 bug,使用 (或隐含) --owner (-o) 选项时, --link-dest 选项在非 root 用户调用 rsync 有问题。

--compress, -z

让 rsync 在向 remote 侧传输文件数据时压缩数据,这可以减少要传输的数据量。一些情况下,这对一些慢速网络连接很有用。

rsync 支持多种压缩算法,并且会自动选择,除非用户使用 --compress-choice (--zc) 选项指定了算法。

运行 rsync --version 可以看到当前 rsync 支持的压缩算法列表。

在两端的 rsync 版本不低于 v3.2.0 时,rsync 选择出现在 client 侧的压缩算法列表中,同时也在 server 侧的压缩算法列表中的第一项。如果两端没有共同支持的压缩算法,rsync 报错并退出。如果 remote rsync 版本太低而不支持校验和协商,那么 remote rsync 的算法列表被设置为 zlib。

压缩算法的默认顺序可以通过环境变量 RSYNC_COMPRESS_LIST 设置,环境变量的值是以空格分隔的,rsync 支持的压缩算法列表。如果环境变量的值包含 "&" 符号,那么该符号前的内容表示 client 可选择的压缩算法,符号之后的内容是允许 server 选择的算法。如果环境变量的值不包含 "&",那么环境变量指定的算法列表同时适用于两端。如果环境变量的值不包含非空白字符 (就是全是空白字符),则 rsync 使用默认的压缩列表。环境变量的值中,任何无法识别的压缩算法名称都会从列表中丢弃,但如果值只包含不能识别的算法名称会导致协商失败。

有一些老的 rsync 版本被设置为拒绝 -z 选项,并且要求使用 -zz 选项,因为它们使用的压缩算法库与默认的 zlib 算法不兼容。通常,用户可以忽略这个奇怪的行为,除非 rsync server 报错并且要求用户使用 -zz

--compress-choice=STR, --zc=STR

被用于取消使用 --compress 选项时默认会做的压缩算法协商,并且使传输的两端使用选项中指定的压缩算法。这个选项隐含了 --compress ,除非该选项的值使用 none ,这个参数值隐含了 --no-compress

压缩算法可以从这些中选: zstd, lz4, zlibx, zlib, none

运行 rsync --version 可以看到当前 rsync 默认支持的压缩算法列表 (命令输出的当前 rsync 支持的压缩算法列表可能与上面的可选压缩算法列表不同)。

注意,如果用户遇到了名为 --old-compress 或者 --new-compress 的报错,这是 rsync 试图发送 --compress-choice=zlib 或者 --compress-choice=zlibx (让更多 rsync 版本可以理解) 以实现向后兼容行为导致。这个错误预示着 server 侧使用了旧的 rsync 版本,并且不允许用户指定压缩算法。

注意,"zlibx" 算法就是 "zlib" 算法,其中匹配的数据从压缩流中排除 (以尝试使其与外部 zlib 实现更兼容)。 译者注: zlibx 算法在原版 zlib 之外多作了一些工作,但是压缩算法的核心一样。

--compress-level=NUM, --zl=NUM

明确地指定压缩算法的级别,而不是使用默认值。如果 NUM 的值不表示不使用压缩的话 (即 NUM 的值表示使用压缩),该选项还隐含了 --compress 。比如,zlib 压缩算法如果使用的压缩级别是 0 则表示不要压缩。

压缩级别的值基于不同的 checksum 算法可以取不同的值。因为 rsync 默认协商如何选择校验和算法 (在 remote rsync 版本足够高时),最好能把 --compress-choice--compress-level 选项结合使用,除非用户确定单用 --compress-level 会生效。比如:

rsync -aiv --zc=zstd --zl=22 host:src/ dest/

译者注: 有些算法不能选择压缩级别,比如 lz4。

对于 zlib 和 zlibx 算法来说,可选的压缩级别是 1-9,默认值 6,0 表示不启用压缩,-1 表示使用默认值 6。

对于 zstd 算法来说,可选的压缩级别是 -131072-22,默认值 3,0 表示使用默认值 3。

对于 lz4 算法来说,没有压缩级别可选,所以它的值总是 0。

如果用户指定了特别大或者特别小的值,那么被用户指定的值被忽略,rsync 会选择一个合理的值。比如用户输入了 --zl=999999999 ,那么不论使用什么算法 rsync 会使用最大的压缩级别。

如果用户想要知道目前使用的压缩级别,使用 --debug=nstr 参数可以看到 negotiated string 结果。这会报告类似于 "Client compress: zstd (level 3)" 的结果 (以及使用了的 checksum 算法信息)。

--skip-compress=LIST

指定要被压缩的文件的后缀的名列表,这个后缀列表会覆盖默认的后缀列表。rsync 针对不同后缀的文件使用不同的压缩级别。如果某个后缀对应的压缩级别的值表示关闭压缩算法,则使用这些后缀的这些文件不会被压缩。支持设置压缩级别的算法使用最小的压缩级别,以尽可能减少压缩匹配到的文件时的 CPU 使用率。

LIST 的值是以 / 分隔的文件后缀名 (不带点)。LIST 为空代表所有文件都不会被跳过压缩。

LIST 的值支持简单的字符类匹配。所谓的字符类由中括号和写在中括号中的一系列的字母组成 (如: 非特殊的字符类 [abcz],特殊的字符类 [:alpha:],注意,短横线"-"在此没有特殊的意义,仅表示一个简单的字符)。

LIST 中的星号 * 和问号 ? 没有特殊的含义。

下面是一个例子,以这 6 个后缀结尾的文件会被跳过 (因为 mp[34] 匹配了 mp3, mp4两种后缀):

--skip-compress=gz/jpg/mp[34]/7z/bz2

--skip-compress 选项在这个版本的默认值是:

3g2 3gp 7z aac ace apk avi bz2 deb dmg ear f4v flac flv gpg
gz iso jar jpeg jpg lrz lz lz4 lzma lzo m1a m1v m2a m2ts m2v
m4a m4b m4p m4r m4v mka mkv mov mp1 mp2 mp3 mp4 mpa mpeg mpg
mpv mts odb odf odg odi odm odp ods odt oga ogg ogm ogv  ogx
opus otg oth otp ots ott oxt png qt rar rpm rz rzip spx
squashfs sxc sxd sxg sxm sxw sz tbz tbz2 tgz tlz ts txz  tzo
vob war webm webp xz z zip zst

上面的默认值会被用户使用 -skip-compress 选项指定的列表覆盖,除了一种情况: 从 rsync daemon 拷贝文件时,用户指定的列表会追加到默认列表之后,而不是覆盖默认列表。rsync daemon 的后缀列表可能与上面的默认列表不同。

--numeric-ids

让 rsync 传输 uid 和 gid,而不是字符格式的 username 和 groupname,然后将其映射到两端。 译者注: 就是在使用用户身份映射时,使用 uid 和 gid 来匹配用户,而不是根据用户名和组名。

默认情况下,rsync 使用用户名和组名字符串来决定如何设置文件的所有者和所属组。但注意,即使没有指定 --numeric-ids 选项,也绝不会通过字符格式的 username 和 groupname 来映射 uid=0 和 gid=0 的用户。 译者注: 有些用户会把 uid=0 和 gid=0 的用户的默认名 (root),改成其他名字,组也类似。

如果在 SRC 主机上的用户或组没有字符格式的名称 (译注:即只有uid和gid,没有 username 和 groupname) ,或者 DEST 主机上没有相同的用户/组,则使用 uid/gid 来设置所有权关系。见 rsyncd.conf 的 man 文档中关于 use chroot 的设置说明,以获取关于 chroot 设置后如何影响 rsync 对用户名和组名的查找能力以及用户能对此做些什么的信息。

--usermap=STRING --groupmap=STRING

允许用户指定映射到接收端的其他用户。STRING 是一个或多个被逗号分隔的 FROM:TO 格式的字符串。任何在发送端与 FROM 匹配的值都会在接收端被替换成 TO。用户可能为 FROM 和 TO 的值指定 username/groupname 或者 uid/gid,并且 FROM 的值可能是通配符 (用来匹配发送端的 username)。通配符不匹配数字的 uid,但 * 可以匹配任何东西。用户可能会使用 LOW-HIGH 格式来匹配多个数字 id。比如:

--usermap=0-99:nobody,wayne:admin,*:normal --groupmap=usr:1,1:usr

译者注: 有时,SRC 指定的目录中包含了多个用户的文件,用户想要把在目录内拥有文件的用户/用户组都映射到 DEST 上对应的,或者其他的用户/用户组。这个选项可以用来帮助处理这种情况。

上面例子中的第一个匹配格式就是使用一个 uid 范围来匹配发送端的用户。

只能使用一个 --usermap / --groupmap 选项来完成所有用户/用户组的映射。

注意,发送端的 id 为 0 的用户和组的名称不会被传输到接收方,因此用户应该使用 0 值来匹配这些用户和组的名称,或者使用接收方认为有效的名称 (通常是 root)。所有 FROM 使用的名字在发送端匹配;所有 TO 使用的名字在接收端匹配。

为了方便匹配,任何在接收端没有名字的 id (指的是,有 uid 但是没有用户名,有 gid 但是没有组名) 都会被处理成它们有空白的 name。这允许它们被星号 * 匹配到,也允许它们被空白 name 匹配到。比如:

--usermap=:nobody --groupmap=*:nobody

在使用 --numeric-ids 选项时,发送端不会发送任何 name 字符串,所以所有的 id 都会按它们有空白的 name 来被处理。这意味着,用户如果映射这些没有名字的 id 到不同的值,需要在 FROM 中指定数字 id。 译者注: 将没有 name,只有 id 的用户映射到其他用户,只能用这个没有 name 的用户的 id 来指定这个用户。

使用 --usermap 选项时,接收端要以 super-user 启动 (见 --super--fake-super 选项)。选项 --groupmap 隐含 --group (-g) 选项。

老版本的 rsync client 可能需要使用 -s 来避免通配符相关的问题,但是现代的 rsync 会自动处理通配符相关的问题。

--chown=USER:GROUP

强制更改所有要被传输的文件的所有权为指定的用户和组。这个选项是简化版的 --usremap--groupmap ,但 --chown 选项的本质是用 --usermap--groupmap 实现的。所以它们不能被混合使用。如果 USER 或者 GROUP 为空,那就不会修改对应的权限。但是如果 USER 为空,GROUP 前必须有一个前导的冒号。

指定 --chown=foo:bar 等同于 --usermap=*:foo --groupmap=*:bar ,只是前者写法更简便 (前者还隐含了 --owner--group 选项)。

老版本的 rsync client 可能需要使用 -s 来避免通配符相关的问题,但是现代的 rsync 会自动处理通配符相关的问题。

--timeout=SECONDS

设置 IO 超时的最大时间,单位为秒。如果在指定时间内没有数据被传输,rsync 将直接退出。默认值为 0 表示永不超时。

--contimeout=SECONDS

设置 rsync 连接 rsync daemon 的等待超时时间。若在指定时间内未连接上rsync daemon,rsync 将报错并退出。

--address=ADDRESS

rsync 连接 rsync daemon 时,默认情况下,rsync 会绑定到通配符地址。这个选项允许用户指定 rsync 绑定的特殊 IP 地址或主机名。

见 daemon 版的 --address 选项的信息。

--port=PORT

指定 rsync daemon 在所在主机上监听的 TCP 端口,而不是使用默认的 873 端口。这个选项仅当用户使用双冒号语法连接到 rsync daemon 时有用 (因为 URL 语法有在 URL 内指定端口的方式)。

见 daemon 版的 --port 选项的信息。

--sockopts=OPTIONS

可以为那些喜欢最大限度地调整系统的人们提供无尽的乐趣。用户可以设置各种套接字选项,这可能会使传输更快 (或更慢!)。阅读 setsockopt() 系统调用的帮助页,了解可以设置的一些选项的详细信息。默认情况下,该选项的值为空。该选项仅影响直接连接到 remote rsync daemon 的套接字。

见 daemon 版的 --sockopts 选项的信息。

--blocking-io

在加载 remote shell 传输时,让 rsync 使用阻塞 I/O。如果 remote shell 是 rsh 或者 remsh 时,rsync 默认使用阻塞 I/O,否则默认使用非阻塞 I/O。(注意,SSH 偏向于使用非阻塞 I/O)

--outbuf=MODE

设置输出缓存的模式。MODE 值可以是 None (不缓存), LineBlock (全量)。可以使用这三个模式的首字母来指定模式,大写小写均可。

这个选项的主要用途是当 rsync 的输出是一个文件或者 pip 时,修改 Full buffering 为 Line buffering。

--itemize-changes, -i

请求显示对每个文件所做的更改的简单逐项列表,包括属性更改。该选项与 --out-format='%i %n%L' 完全相同。如果重复该选项,未更改的文件也会被输出,但前提是接收端 rsync 版本至少为 v2.6.7 (可以对旧版本的 rsync 使用 -vv,但这也会打开其他详细消息的输出)。

"%i" 转义符有一个长 11 字符的输出。这个输出的一般格式是 YXcstpoguaxf ,其中 Y 是正在执行的更新类型,X 是文件类型,其他字母表示在修改时可能输出的属性。

表示更新类型的 Y 有以下值:

  • < 文件被传输到 remote 主机 (发送)
  • > 文件被传输到 local 主机 (接收)
  • c 有发生在本地的项目修改/创建 (比如创建了一个目录,或者修改了一个符号链接等)
  • h 条目有硬链接到其他的条目 (前提是使用了 --hard-links 选项)
  • . 条目没有被更新 (尽管它的元数据可能被更新了)
  • * 逐项列表的剩余部分包含信息 (比如包含了 "deleting" 信息)

表示文件类型的 X 的值有: f 文件, d 目录, L 符号链接, D 设备, S 特殊文件 (比如被命名的 socket 和 fifo)。

YXcstpoguaxf 中,除了 YX 的其他字符表示了是否修改了文件的属性:

  • . 属性未被更改
  • + 文件是新创建的
  • " " (空格) 所有属性都未被修改 (所有的点都变成空格)
  • ? 发生未知修改 (remote rsync 版本太老的时候出现)
  • 字母正常意味着这个属性被修改了

文件属性与 YXcstpoguaxfcstpoguaxf 的对应关系如下:

  • c 一个常规文件有不同的校验和 (要求使用 --checksum 选项),或者符号链接、设备或者特殊文件中的值有改变。注意,如果用户发送文件到 v3.0.1 之前的 rsync,这个标志将仅出现在校验和不同的常规文件上
  • s 文件的大小不同,并且会被更新
  • t mtime 的值不同,要被更新为发送端的 mtime (要求使用 --times 选项)。该位置还可能出现 T 表示 mtime 将会被设置为传输该文件时的时间,当文件/符号链接/设备在不使用 --times 选项的情况下更新时,以及当符号链接被更改而接收端无法设置其时间时,就会发生这种情况 (注意: 当使用 rsync v3.0.0 client,时间设置失败时,用户可能看到 st 而不是 T)
  • p 权限不同,要被更新为发送端的值 (要求使用 --perms 选项)
  • o 属主不同,要被更新为发送端的值 (要求使用 --owner 选项与 super-user 权限)
  • g 属组不同,要被更新为发送端的值 (要求使用 --group 选项与 super-user 权限)
  • u 的位置可能有其他值: u | n | b
    • u atime 不同,要被更新为发送端的值 (要求使用 --atimes 选项)
    • n ctime 不同,要被更新为发送端的值 (要求使用 --ctimes 选项)
    • b atime 和 ctime 都不同,并且都要被更新为发送端的值
  • a ACL 信息要被修改
  • x 扩展属性信息要被修改

也有可能出现其他输出: 在删除文件时,"%i" 将为每个要被删除的条目输出字符串 "*deleting" (假设用户正在与足够新的 rsync 交互,它会记录删除内容,而不是将它们作为详细消息输出)

--out-format=FORMAT

允许用户准确指定 rsync client 在每次更新条目时向用户输出的内容。FORMAT 是一个字符串,包含以 % 字符为前缀的嵌入式单字符转义序列。如果指定了 --info=name-v 选项,则假定默认格式为 "%n%L" (这输出文件的名称,如果文件是符号链接,则输出它指向的位置)。有关可能的转义字符的完整列表,请参阅 rsyncd.conf manpage 中的日志格式设置。

译者注: 我没完全弄明白下面两段作者在说啥。

--out-format 选项隐含了 --info=name 选项,它会输出以重要方式更新 (这个重要方式是指,文件被传输、符号链接/设备被重新创建,touched directory) 的每个文件、目录等。此外,如果 FORMAT 中包含 itemize-changes 转义符 (%i) (比如使用了 --itemize-chances 选项),则 logging of names 会增长以提及以任何方式更改的任何条目 (只要接收端的 rsync 版本不小于 v2.6.4)。有关 "%i" 输出的描述,参阅 --itemize-changes 选项。

译者注: 上面那个 touched directory 我没搞懂作者在说啥。touch 命令可以作用于文件,达到修改文件 atime 和 mtime 的效果,也可以用于创建不存在的文件,但是 touched directory,可能是在说被修改了 atime 和 mtime 的目录吧。

译者注: 上面那个 logging of names,我猜,作者可能是想说,每一个输出条目会有增加的字段,以输出更多信息的意思。

rsync 将在文件传输之前,输出输出格式字符串,除非请求传输统计信息转义之一,在这种情况下,日志记录是在文件传输结束时完成的。当延迟的日志记录行为生效并且还指定了 --progress 时,rsync 还将在其进度信息之前输出正在传输的文件的名称 (当然,后面是 FORMAT 格式的输出)。

译者注: 上面的 请求传输统计信息的转义之一 的原文是 one of the transfer-statistic escapes 。我没搞懂作者想说啥。

--log-file=FILE

在 FILE 中记录 rsync 的行为。与 rsync daemon 的日志操作相似,但可以在 rsync 传输时的两侧或某一侧要求 rsync 记录日志。如果该选项在 client 侧生效,"%i %n%L" 格式的传输日志会被记录。如果用户想要覆盖这个格式, --log-file-format 选项描述了更多信息。

这是要求 remote rsync 记录日志的命令:

rsync -av --remote-option=--log-file/tmp/rlog src/ dest

这在用户需要 debug 为什么连接被关闭的问题时很有用。

见 daemon 版的 --log-file 选项的信息。

--log-file-format=FORMAT

允许用户指定准确的每个更新的日志格式到 --log-file 选项指定的文件中 (--log-file 选项必须使用,否则该选项不生效)。如果用户将该选项的值设为空,被更新的文件将不会在日志中被提到。要获得完整的转义字符的列表,见 rsyncd.conf manpage 中的 log format 设置。

如果使用了 --log-file 选项,默认的 FORMAT 值是 "%i %n%L"。

见 daemon 版的 --log-file-format 选项的信息。

--stats

让 rsync 输出文件传输过程中的详细统计数据,从中可以看出增量算法的效率如何。这个选项等于 --info=stats2 选项与 0 或 1 个 -v 选项一起用;或者 --info=stats3 与 2 个及以上的 -v 选项一起用。

目前的统计信息有:

  • Number of files 是广义上的文件的数量,它包含了目录、符号链接等。总数后面是按文件类型列出的计数列表 (如果总数不为 0 的话)。比如计数列表 (reg: 5, dir: 3, link: 2, dev: 1, special: 1) 列出了常规文件的总数、目录总数、符号链接总数、设备文件总数以及特殊文件总数。
  • Number of created files 是被创建的广义上的文件的数量 (被更新的文件不被计入)。总数后面是按文件类型列出的计数列表 (如果总数不为 0 的话)。
  • Number of deleted files 是被删除的广义上的文件的数量。总数后面是按文件类型列出的计数列表 (如果总数不为 0 的话)。注意,仅当有文件被删除且使用 protocol 31 (rsync 3.1.x 默认的 protocol version) 时才会输出此行。 译者注: 后面这句注意是错的。在 v3.2.7 中,即使没有文件被删除,也会显示该项,只是值为 0。
  • Number of regular files transferred 是被 rsync 增量更新算法更新的普通文件的总数,它不包括目录,符号链接等。注意,rsync v3.1.0 添加了一个 "regular" 单词在这条输出的开头。 译者注: 在 v3.2.7 中没有在这条输出的开头发现 regular 单词。可能,作者是想说 Number of regular files transferred 中的这个 regualr。
  • Total file size 是被传输的文件大小的总和。它不计入目录或特殊文件的大小,但包括符号链接的大小。
  • Total transferred file size 是要传输的文件真正被传输的数据大小的总和。
  • Literal data 是被传输到接收端的,更新已有文件到最新版的,数据的总和。
  • Matched data 是接收端更新已有文件到最新版时,从本地读取的数据的总和。
  • File list size 是发送端发给接收端的,要被传输的文件列表的,数据的大小。这个值比文件列表在内存中占用的空间小,因为发送时有压缩。
  • File list generation time 是发送端创建要被发送的文件列表的耗时,单位是秒。发送端使用现代 rsync 时才能生成这个条目。
  • File list transfer time 是发送端发送文件列表到接收端所花费的时间。
  • Total bytes sent 是 rsync client 发送到 server 的所有数据量,以 byte 计。
  • Total bytes received 是接收端从发送端接收到的 non-message 类型的数据量。non-message 类型的数据是发送端发送给接收端的消息数据,不计入这种类型的数据可以让统计信息更一致。

--8-bit-output, -8

让 rsync 在输出中保留所有高位字符的非转义形式,而不是尝试检测它们是否在当前区域设置中有效,并转义无效的字符。无论这个选项的设置如何,所有控制字符 (但不包括制表符) 都总是被转义。

自 v2.6.7 开始的转义习惯是输出一个字面的反斜杠 (\) 和一个井号 (#),后跟精确的 3 个八进制数字。例如,换行符将输出为 "#012"。除非跟随一个井号和 3 个数字 (0-9),否则文件名中的字面反斜杠不会被转义。

--human-readable, -h

让输出中的数字被转换成容易被人类阅读的格式。下面是三个级别:

  1. 让输出的数字从低位开始,每三位之间添加一个分隔符。根据小数点的表示方式,可以选择逗号或句点作为分隔符。如果小数点用句点表示,则使用句点作为分隔符;如果小数点用逗号表示,则使用逗号作为分隔符。
  2. 使用 1000 为进位,在每个数字后添加单位。
  3. 使用 1024 为进位,在每个数字后添加单位。

默认的人类可读的级别 (human-readable level) 是 1。每一个 -h 参数会提升一个级别。用户通过设置 --no-human-readable (--no-h) 可以让级别为 0 (让我有数据以纯数字格式输出)。

译者注: 不使用 -h 选项时,默认级别是 1,用一个 -h 级别是 2。用 --no-h 级别变成 0。

级别为 2 和 3 时使用的字母有: K (kilo), M (mega), G (giga), T (tera) 或 P (peta)。比如,1234567 byte 大小的文件在级别 2 下被输出为 1.23M (假设句号点是本地使用的小数分隔符)。

向后兼容需要注意: 早于 v3.1.0 版本的 rsync 不支持级别 1,并且默认的级别是 0。因此,只要在一个或多个 -h 选项之前没有指定 --no-h 选项,那么指定一个或两个 -h 选项将在旧版本和新版本中以类似的方式运行。有一个区别可以参考 --list-only 选项。

译者注: 以新版本的级别为基准。旧版本 rsync 支持的级别是 0 2 3,新版本 rsync 支持的级别是 0 1 2 3。

译者注: 新版上 --no-h -hh 表示级别 2;在旧版上 --no-h -hh 也表示级别 3。新版上 -hh 表示级别 3;在旧版上 -hh 表示级别 3。

--partial

默认情况下,rsync 在传输被打断后,开始下一次传输时,会删除没有传输完成的文件,重新开始传输。在一些情况下,用户希望接着上次的进度继续传输。使用这个选项可以让 rsync 接着上次已经传输的部分继续传输剩余的部分,这可能会让传输更快。

--partial-dir=DIR

这个选项隐含了 --partial 选项,并且修改了 --partial 选项的行为。这个选项让 rsync 先把文件传输到 DIR 目录中,而不是直接写入 DEST 指定的路径中。在被打断后的下一次传输中,rsync 会从 DIR 目录中找到未传输的文件,接着上次的进度继续传输,传输完成后 DIR 目录会被删除。

注意,如果使用了 --whole-file 选项 (或者隐含这个选项),在传输开始时,任何在 DIR 目录中被找到的文件都会被删除。(因为使用了 --whole-file 的 rsync 不使用 rsync 的增量传输算法来传输文件,而 --partial 选项依赖增量传输算法)

译者注: 下一段讲 DIR 如何被创建和删除,但我从第二句开始就每看懂,所以下面这段从第二句开始可能是错的。我自己用译者注重写了。

如果 DIR 不存在,那么 rsync 会创建这个目录,但只创建用户给出的目录路径的最后一级,而不是整个路径。这让用户在需要时,可以使用相对路径 (比如 --partial-dir=.rsync-partial)。rsync 会在目前的工作目录中创建目录,并在该工作目录下的文件被传输完成并移走后删除这个目录。注意,删除目录的行为只会删除 DIR 的最后一级目录,因为从倒数第二级往上的目录都是预先存在的目录。

译者注: 这个只创建最后一级目录是指,如果 DIR 的值为 /tmp/dir1/dir11,那么 /tmp/dir1 必须预先存在。

译者注: 如果 DIR 不存在,那么 rsync 会自动创建这个目录。如果 DIR 是一个绝对路径,那么 rsync 会创建此绝对路径,并使用该路径对应的目录存储未传输完成的文件,所有文件都被传输完成后,该绝对路径对应的目录被删除。如果 DIR 是一个相对路径,那么这个相对路径是相对于 rsync 目前的工作目录的路径。比如使用 --partial-dir=rsync_partial 选项的情况下,当 rsync 目前正在接收 /recv/tgt/dir1 目录下的文件时,rsync 会创建 /recv/tgt/dir1/rsync_partial 目录作为接收未传输完成的文件的目录。当 /recv/tgt/dir1 目录下的文件都被接收完时 (即 /recv/tgt/dir1/rsync_partial 目录中存储了全部的,应位于 /recv/tgt/dir1 中的文件),rsync 会把 /recv/tgt/dir1/rsync_partial 中的数据移动到 /recv/tgt/dir1 中,移动完成后 /recv/tgt/dir1/rsync_partial 是个空目录,最后会被删除。

如果 DIR 不是绝对路径,rsync 将在所有现有的排除规则之后添加一个排除规则。这条最后加上去的排除规则可以让接收端不发送任何可能存在于发送端的 DIR 路径中的文件,并且还能阻止接收端不适时地删除 partial-dir 中的文件的行为。例如,上述的 --partial-dir 选项将在任何其他过滤规则的末尾添加相当于以下的 perishable 排除规则: -f '-p .rsync-partial/'

如果用户使用了自己定义的 exclude 规则,用户可能需要添加自己的应用于 DIR 的 exclude/hide/protect 规则,因为:

  1. 在其他规则的末尾,自动添加的规则可能无效
  2. 用户可能希望覆盖 rsync 的 exclude 选择

例如,如果用户希望让 rsync 清理可能存在的任何剩余的 DIR,应该指定 --delete-after 并添加一个 risk 过滤规则,例如 -f 'R .rsync-partial/' 。除非不需要 rsync 在当前运行期间使用任何 DIR 中残留的数据,否则请避免使用 --delete-before--delete-during

译者注: --delete-before--delete-during 都会在 rsync 传输当前目录中的数据前,删除当前目录下,没有在接收端出现的目录或文件。这样一来 DIR 中的数据就无法被使用了,这意味着不能接着上次的进度继续传数据,只能重新开始传输。

重要提示: DIR 不应该对其他用户可写,否则存在安全风险!例如,避免使用 /tmp 作为 DIR 的值!

还可以通过设置 RSYNC_PARTIAL_DIR 环境变量来指定 DIR 的值。设置此环境变量不会强制启用 --partial 选项,而是影响指定 --partial 时未传输完成的文件的存放位置。例如,可以在环境中设置 RSYNC_PARTIAL_DIR=.rsync-tmp ,然后使用 -P (--partial --progress) 选项让 .rsync-tmp 目录生效 (存放未传输完成的文件),而不是使用 --partial-dir=.rsync-tmp--progress 选项。使用 --partial 选项时,满足如下条件则 RSYNC_PARTIAL_DIR 环境变量失效:

  1. 使用 --inplace 选项 (因为 --inplace--partial-dir 冲突)
  2. 使用 --delay-updates 选项 (详见下文)。

当现代的 rsync 接着 DIR 中的文件的进度继续传输时,DIR 中的部分文件现在会原地更新,而不是根据 DIR 中已有的,传输被打断的文件的数据再拷贝出一个副本来,然后接着传输 (因此,DIR 中数据的最大大小为,目标文件 + 正在传输的文件,而不是目标文件 + 传输被打断的文件 + 正在传输的文件)。这要求传输的两端的 rsync 版本不小于 v3.2.0。

译者注: DIR 中未传输完成的文件只能有一个。当文件传输完成后会被移动到目标目录,但是当一个文件被传输完成后,下一个传输会立即开始。这就有可能导致,上一个传输完成的文件还没来得及移走,下一个文件的传输已经开始了。此时 DIR 内就有一个目标文件和一个未传输完成的文件。

译者注: 下面这段关于 refuse options 的内容我没读懂,但是我尽量把能用中文表达的地方翻译了。

对于 daemon 配置文件中的 refuse options 设置而言,选项 --partial-dir 并不隐含 --partial 。这样一来,拒绝 --partial 选项可以禁止 partial file 覆盖目标文件,同时仍然允许使用 --partial-dir 选项提供的更安全的 idiom。

--delay-updates

让 rsync 将每一个要被更新的文件放入一个临时目录,待传输全部完成之后,所有在临时目录中的文件会被以重命名的方式移动到指定位置。这个旋谍试图使文件的更新更具有原子性。默认情况下,新的文件被放在其目标位置同级的 .~tmp~ 目录中,但是如果用户指定了 --partial-dir 选项,那么就使用该选项指定的目录代替。选项 --partial-dir 的文档说明了如何将 .~tmp~ 目录从传输中排除,也讲解了如果用户希望 rsync 清理可能存在的旧的 .~tmp~ 目录时可以做什么。该选项与 --inplace--append 选项冲突。

译者注: rsync 默认情况下会在与要被更新的文件同级的目录下创建临时文件,然后用临时文件覆盖要被更新的文件。这个选项的作用是,把同级目录下的所有临时文件收集起来,等所有文件都传完了,一次性更新所有文件。

该选项隐含了 --no-inc-recursive ,因为接收端的 rsync 需要将完整的目录结构保存在内存中,以便在传输结束之后移动传输来的数据文件。而接收端的目录结构又是发送端发来的,所以发送端就需要在文件传输开始前先把目录结构发给接收端,这样只有发送端使用 --no-inc-recursive 禁用增量递归才能在传输开始之前获取完整的目录结构。

该选项将使接收端的 rsync 使用更多的内存 (每个传输的文件使用一个比特) 并且还需要足够的空闲磁盘空间来保存所有更新文件的额外副本。还请注意,除非以下情况,否则不应该使用绝对路径作为 --partial-dir 的参数:

译者注: 如果不存在下面两个情况,那么 --delay-updates--partial-dir 选项可以一起用。

  1. 所有要被传输的文件中,没有同名的文件。(因为所有的文件都会被放进同一个目录中,如果有同名文件则先传输过来的文件会被后传输过来的文件覆盖)
  2. 目标目录的结构中不能有挂载点。(因为最后移动文件时候调的是 rename 而不是 mv 命令,rename 可以跨目录,但不能跨挂载点)

可以在 rsync 源码目录中 support 目录中的 atomic-rsync Python 脚本中找到更具原子性的更新算法。(该脚本使用 --link-dest 选项和文件的并行结构)

--prune-empty-dirs, -m

让接收端的 rsync 从文件列表中删除空目录,包括没有非目录子项的嵌套目录。这可以避免发送端的 rsync 使用 include/include/filter 规则递归扫描文件层次结构时创建大量无用的目录。

如果使用了 TRANSFER_RULES,即使使用此选项,仍然可能在接收端保留空目录。

由于传输列表被修改,该选项还影响使用 --delete 选项时删除哪些目录。然而,注意,由于 exclude 规则隐藏了源文件,而且保护了目标文件,赛意被排除的文件和目录可以保护存在的条目不被删除。有关如何避免这种情况,请参考 perishable 过滤规则。

可以通过使用全局的 protect 过滤器来防止对传输列表中某些空目录的修剪。例如,以下选项将确保目录 emptydir 在文件列表中保留:

--filter 'protect emptydir/'

下面是一个例子,它复制目录层次结构中的所有 .pdf 文件,只创建必要的目标目录来保存 .pdf 文件,并确保删除接收端中任何多余的文件和目录 (注意,此处使用的是 hide 过滤器来过滤非目录文件,而不是使用 exclude):

rsync -avm --del --include'*.pdf' -f 'hide,~ */' src/ dest

如果不希望删除接收端多余的文件,那么更常用的选项 --include='*/' --exclude='*' 可以很好地替代 hide 过滤器。

--progress

让 rsync 输出传输进度信息,以便用户可以观察传输的进展。对于无聊的用户来说,这提供了一些可以观看的内容。在现代的 rsync 中,该选项与指定 --info=flist2,name,progress 相同,但用户提供的这些 info 标志的设置优先级更高 (例如 --info=flist0 --progress 中的 flist0 可以覆盖 --progress 选项中的 flist2)。

当 rsync 传输常规文件时,它会更新一个类似于以下样式的进度:

782448  63%  110.64kB/s    0:00:04

在这个例子中,接收端已经重建了 782448 字节,这是发送端文件的 63%,重建速度为每秒 110.64kB,如果当前速度保持到最后,传输将在 4 秒内完成。

如果 rsync 正在使用增量传输算法,这些统计数据可能有误导性。例如,如果发送端的文件由基础文件数据后跟附加数据组成,在接收端处理字面数据时,报告的传输速度可能会急剧下降,并且传输可能需要比接收端在完成文件的匹配部分时估计的时间更长。

当文件传输完成,rsync 使用类似这样的摘要行替换进度行:

1,238,099 100%  146.38kB/s	0:00:08	 (xfr#5, to-chk=169/396)

在这个例子中,文件共有 1,238,099 字节,整个文件的平均传输速率为每秒 146.38kB,传输完成需要 8 秒。这是当前 rsync 会话中常规文件的第 5 次传输,接收端还有 169 个文件需要检查 (还有 169 个文件没有确认是否需要更新),剩下的 396 表示文件列表中的总文件数。

译者注: 上面的那个 5 也可以理解成,当前在传输的文件是本次传输中,第 5 个被传输的文件。非常规文件不被计算在内,比如,符号链接和目录不被计算在内,但是会被计入总数。

在使用增量递归扫描目录结构的过程中,rsync 在扫描结束之前无法知道文件列表中的总文件数,但由于它在扫描期间就开始传输文件,所以进度行会显示 ir-chk (表示增量递归扫描还未结束) 而不是 to-chk。直到 rsync 扫描完毕,获取完整的传输列表后,ir-chk 将切被换到 to-chk。因此,看到 ir-chk 可以让用户知道文件列表中的文件总数仍将增加 (每次增加时,要检查的文件数的增加值与传输列表总条目的增加值相同)。

-P

等于 --partial --progress 一起用。这个选项用于哪些可能会被打断的长时间的传输,可以减少命令的长度。

还有一个 --info=progress2 选项,这个选项与 --progress 不同, --info=progress2 输出的是整个传输的统计信息,而不会基于单个文件输出统计信息。如果用户希望在不显示大量文件名的情况下查看传输的进度,应使用 --info=progress2 ,并避免使用 -v 选项或 --info=name0 。这样可以更直观地查看传输的进行情况,而无需滚动屏幕查看大量文件名。

最后,可以通过向 rsync 发送 SIGINFO 或 SIGVTALRM 信号来获得即时的进度报告。在 BSD 系统上,通过快捷键 Ctrl+T 生成 SIGINFO 信号 (Linux 目前不支持 SIGINFO 信号)。当 client 进程接收到这些信号之一时,它会设置一个标志,在当前文件传输完成后输出一条进度报告 (因此,如果在信号到达时正在处理大文件,可能需要等大文件传输完成,才能看到报告)。首先输出文件名(如果需要),然后输出 --info=progress2 格式的进度信息。如果您不知道 3 个 rsync 进程中的哪一个是 client 进程,可以向它们所有进程发送信号 (因为非 client 进程会忽略该信号)。

小心: 向 pre-3.2.0 之前版本的 rsync 发送 SIGVTALRM 信号会杀死进程。

--password-file=FILE

让 rsync 可以通过 FILE 中存储的密码连接到 rsync daemon,如果 FILE 的位置是字符 - (横线) 则从标准输入中读取密码。应当只将密码放在文件的首行 (除了首行之外的其他行会被忽略)。如果 FILE 全局可读,或者以 root 权限启动的 rsync 发现 FILE 的所有者不是 root,rsync 直接退出。

该选项无法为 remote shell (如 ssh) 提供密码,至于如何为 remote shell 供密码,参考对应 remote shell的文档。当使用 remote shell 访问 rsync daemon 时,该选项只有完成 remote shell 的身份验证后才对 rsync daemon 生效。

译者注: 对于 ssh 而言,使用公钥认证机制即可。

--early-input=FILE

允许 rsync 将最多 5K 的数据发送到其标准输入上的 early exec 脚本。此数据的一个可能用途是向脚本传递密钥,用于挂载加密文件系统 (用户应该在 post-xfer exec 脚本中卸载该文件系统)。

rsync daemon 的版本至少为 v3.2.1。

--list-only

让 rsync 列出源文件而不传输它们。如果只有一个 SRC 且没有 DEST 参数,则自动使用此选项。该选项的主要用途是:

  1. 将包含 DEST 的复制命令转换为一个列出 SRC 文件的命令
  2. 允许指定多个 SRC 参数。注意:务必包含 DEST 参数

注意,带有通配符的 SRC 参数会被 shell 扩展为多个参数,因此在只有一个 SRC 参数,没有 DEST 参数时,使用通配符是不安全的。请谨慎使用。一个安全使用该选项的例子是:

译者注: 结合上面提到的第二个用途来理解。如果 rsync 命令里只有使用了通配符的 SRC 参数,而没有 DEST 参数,那么 SRC 会被 shell 展开成多个参数,而被展开的最后一个参数被按照 DEST 参数处理。如果 SRC 被展开以后还是只有一个参数,那么不存在该问题。

rsync -av --list-only foo* dest/

这个选项总是使用如下格式的输出:

drwxrwxr-x 4,096 2022/09/30 12:53:11 support
-rw-rw-r--    80 2005/01/11 10:37:37 support/Makefile

截至版本 3.1.0,唯一影响此输出风格的选项是 --human-readable (-h) 选项。默认情况下,以字节计数输出大小,并带有数字分隔符 (列宽 14 个字符)。至少指定一个 -h 选项将使大小输出带有单位后缀。如果用户希望使用旧式的字节计数大小,没有数字分隔符 (并且列宽是 11 个字符),请使用 --no-h 选项。

兼容性注意事项: 从 v2.6.3 或更早的 remote rsync 请求文件列表时,如果请求一个非递归列表,可能会遇到错误。这是因为,输出文件列表意味着使用 --dirs 选项但不带 --recursive 选项,而旧版本的 rsync 没有 --dirs 选项。为避免此问题,要么指定 --no-dirs 选项 (如果不需要展开目录的内容),要么启用递归并排除子目录的内容: -r --exclude='/*/*'

--bwlimit=RATE

允许用户指定 rsync 传输数据时,每秒的最大速率。RATE 值可以在末尾添加字符以表示大小的乘数,也可以是一个小数值 (例如 --bwlimit=1.5m)。如果没有指定后缀,该值将被假定为以 1024 字节为单位 (就像添加了 K 或 KiB 一样)。有关所有可用后缀的描述,请参见 --max-size 选项。值取 0 表示没有限制。

出于向后兼容的考虑,速率限制的值将被四舍五入到最近的 KiB 单位,因此不可能设置小于 1024byte/s 的速率。

rsync 通过 socket 以数据块 (block) 的形式写入数据,该选项限制 rsync 写入的块的大小,并尝试保持平均传输速率在请求的限制内。rsync 写入一块数据并休眠以使平均速率符合要求时,可能会出现一些突发性写入。

由于数据的内部缓冲, --progress 选项可能不会准确反映数据发送的速度。这是因为当数据被快速缓存时,一些文件可能会显示为快速发送,而当输出缓冲被刷新时,其他文件可能显示为非常慢。这个问题可能在未来的版本中得到修复。

译者注: 上面那段作者可能想说的是,有些文件在发送前被缓存了,rsync 从缓存中取数据并发出去就特别快,连带着,传输速度也会显示特别高。但是数据没有被缓存时,找数据并把数据发出就比较慢,连带着,传输速度也会显示得比较慢。

见 daemon 版的 --bwlimit 选项的信息。

--stop-after=MINS, (--time-limit=MINS)

让 rsync 在指定的分钟数过去后停止传输。

为了提高灵活性,rsync 不会将此选项发送给 remote rsync,因为通常只需要连接的一侧按照指定的方式退出,另一端也会退出。这使得即使连接的一侧不支持该选项,也可以使用此选项。如果有需要,用户可以使用 --remote-option (-M) 告知 remote rsync 关于时间的限制。

旧的 --time-limit 选项已被废弃。

--stop-at=y-m-dTh:m

让 rsync 在指定的日期和时间停止传输。日期和时间可以完全用数字格式指定,格式为 year-month-dayThour:minute (例如 2000-12-31T23:59),以本地时区为准。用户还可以使用斜杠 / 而不是短横线 - 来分隔日期数字。

该值还可以以各种方式缩写,比如指定 2 位数的年份和/或省略不同的值。在所有情况下,该值将被视为满足提供的信息的下一个可能的时间点。如果该值指定了当前时间或过去的时间,rsync 将退出并报错。

例如 "1-30" 指定了下一个 1 月 30 日 (当地时间午夜),"14:00" 指定了下一个下午 2 点,"1" 指定了下一个月的 1 日午夜,"31" 指定了下一个可以在 31 日停止的月份,":59" 指定了本小时后的下一个小时的第 59 分钟。

为了提高灵活性,rsync 不会将此选项发送给 remote rsync,因为通常只需要连接的一侧按照指定的方式退出,另一端也会退出。这使得即使连接的一侧不支持该选项,也可以使用此选项。如果有需要,用户可以使用 --remote-option (-M) 告知 remote rsync 关于时间的限制。

--fsync

让接收端在每个完成的文件上执行 fsync。这可能会减慢传输速度,但在更新关键文件时有助于提供心理安慰。

--write-batch=FILE

记录一个文件,该文件以后可以使用 --read-batch 选项应用到另一个完全相同的目标。详见 批处理模式 一节,还可以使用 --only-write-batch 选项。

此选项覆盖了协商的校验和算法和压缩算法,并总是在老式的 md5/md4/zlib 算法间协商。如果想选择更现代的选项,请使用 --checksum-choice (--cc) 和/或 --compress-choice (--zc) 选项。

--only-write-batch=FILE

--write-batch 的工作方式类似,但在创建批处理时不会对目标系统做任何更新。这使得用户可以通过其他方式将更改传输到目标系统,然后通过 --read-batch 应用更改。

注意,可以将批处理直接写入一些便携设备: 如果在传输结束之前设备已满,只需将部分传输应用到目标系统,并重复整个过程以获取其余的更改 (只要用户不介意在更新周期到来时,目标系统有某部分被更新)。

同时,注意,只有在将更改推送到远程系统时才会节省带宽,因为这样批处理的数据可以从发送端转移到批处理文件,而无需通过网络流向接收端 (拉取数据时,发送端是 remote 主机,因此无法写入批处理)。

--read-batch=FILE

应用存储在文件 FILE 中的所有更改,FILE 文件是先前由 --write-batch 生成的。如果 FILE 位置使用短横线字符 - ,则批处理数据将从标准输入读取。详见 批处理模式 一节。

--protocol=NUM

强制使用指定的协议版本。这对于创建与旧版本 rsync 兼容的批处理文件很有用。例如,如果使用 rsync v2.6.4 与 --write-batch 选项,但在运行 --read-batch 选项时使用 rsync v2.6.3,则应在创建批处理文件时使用 --protocol=28 来强制使用旧的协议版本 (假设无法升级发生读取的系统上的 rsync)。

--iconv=CONVERT_SPEC

rsync 可以使用这个选项在字符集之间转换文件名。将 CONVERT_SPEC 设置为 "." 让 rsync 通过区域设置查找默认字符集。或者,可以通过使用形如 --iconv=LOCAL,REMOTE 的用逗号分隔本地字符集和远程字符集来完全指定要进行的转换,例如 --iconv=utf8,iso88591 。这个顺序确保无论推送还是拉取文件,选项都保持不变。最后,可以指定 --no-iconv 或设置 CONVERT_SPEC 为 "-" 来关闭任何转换。该选项的默认设置是特定于站点的,还可以通过 RSYNC_ICONV 环境变量来影响。

要查看本地 iconv 库支持的字符集名称列表,可以运行 iconv --list 来查看。

如果指定了 --secluded-args (-s) 选项,rsync 将转换命令行上指定的要发送到远程主机的文件名。还可以参考 --files-from 选项。

注意,rsync 不会对 filter 文件 (包括 include/exclude 文件) 中的名称进行任何转换。用户需要确保指定的匹配规则可以在传输的两端都匹配。例如,如果传输的两端存在文件名差异,用户可以指定额外的 include/exclude 规则来进行处理。

当用户向允许使用 --iconv 选项的 rsync daemon 传递此选项时,rsync daemon 会使用其 charset 配置参数中指定的字符集,而不管用户实际传递的远程字符集是什么。因此,用户可以自由地仅指定本地字符集进行 rsync daemon 的传输 (例如 --iconv=utf8)。

--ipv4, -4 或 --ipv6, -6

告诉 rsync 在创建 socket 或运行 ssh 时优先使用 IPv4/IPv6。这会影响 rsync 直接控制的 socket,比如直接与 rsync daemon 建立联系时的传出 socket,以及如果 rsync 能够推断出 ssh 是 remote shell 的话,会将 -4-6 选项转发给 ssh。对于其他 remote shell,需要直接指定 --rsh <SHELL> -4 选项 (或使用它使用的任何 IPv4/IPv6 提示选项)。

见 daemon 版的 --ipv4, -4--ipv6, -6 选项的信息。

如果 rsync 在编译时没有支持 IPv6,那么 --ipv6 选项将不起作用。在这种情况下,rsync 的 --version 输出将包含 "no IPv6" 以表示不支持 IPv6。这意味着无法使用 --ipv6 选项来强制 rsync 使用 IPv6。

--checksum-seed=NUM

将校验和种子设置为整数 NUM。这个 4 字节的校验和种子包含在每个数据块和 MD4 文件校验和计算中 (更现代的 MD5 算法不使用种子)。默认情况下,校验和种子由服务器生成,并默认为当前 time() 返回的时间戳。该选项用于设置特定的校验和种子,对于希望得到可重现块校验和的程序或者用户希望得到更随机的校验和种子的情况很有用。将 NUM 设为 0 会导致 rsync 使用 time() 返回的时间戳作为校验和种子。

18. rsync daemon 选项

以下选项只允许在启动 rsync daemon 时使用:

--daemon

让 rsync 作为守护进程运行。被启动的守护进程可以使用 rsync client 通过 host::modulersync://host/module/ 语法访问。

如果标准输入是一个套接字,那么 rsync 将假定它是通过 inetd 运行的;否则,它将从当前终端分离,并成为一个后台守护进程。守护进程会在每次客户端连接时读取配置文件 (rsyncd.conf),并根据请求进行响应。

详见 rsyncd.conf(5) manpage。

--address=ADDRESS

默认情况下,当使用 --daemon 选项运行 rsync daemon 时,rsync 将绑定到通配符地址。而 --address 选项允许指定要绑定到的特定 IP 地址 (或主机名)。这使得用户可以使用 --config 选项启动多个绑定在不同 IP 地址的,具有不同配置的 rsync daemon。

另见 rsyncd.conf(5) manpage 中的 address 全局选项,以及 client 版本的 --address 选项。

--bwlimit=RATE

指定 daemon 发送到套接字的数据的最大传输速率。client 仍然可以指定较小的 --bwlimit 值,但不允许使用更大的值。

详见 client 版本的 ~--bwlimit~选项。

--config=FILE

显示指明要使用的配置文件。这个选项只在使用 --daemon 选项时才有效。默认情况下,配置文件为 /etc/rsyncd.conf,除非 daemon 通过 remote shell 启动,并且 remote 用户不是 super-user;这种情况下,默认配置文件为当前目录中的 rsyncd.conf (通常为 $HOME/rsyncd.conf)。

--dparam=OVERRIDE, -M

启动 rsync daemon 时设置 daemon 的配置参数。相当于在第一个 module 之前,全局设置的末尾添加参数。比如:

rsync --daemon -M pidfile=/path/rsync.pid

译者注: 也可以写成 rsync --daemon -Mpidfile=/path/rsync.pid

--no-detach

启动 rsync daemon 时不让 daemon 成为后台进程。在 Cygwin 上作为服务运行时,此选项是必需的,当 rsync 被类似于 daemontools 或 AIX 的 System Resource Controller 这样的程序监控时,也可能很有用。在使用调试器运行 rsync 时,建议使用 --no-detach 选项。如果 rsync 是通过 inetd 或 sshd 运行的,则此选项无效。

--port=PORT

指定 rsync daemon 要监听的 TCP 端口号,而不是默认的 873 端口。

见 client 版本的 --port 选项和 rsyncd.conf(5) manpage 中的 port 全局设置。

--log-file=FILE

让 rsync daemon 使用指定的日志文件,而不是使用配置文件中的 log file 字段的设置。

见 client 版本的 --log-file 选项。

--log-file-format=FORMAT

让 rsync daemon 使用给定的 FORMAT 字符串,而不是使用配置文件中 log format 字段的设置。它还会启用 transfer logging,除非字符串为空。字符串为空时,将关闭传输日志。

见 client 版本的 --log-file-format 选项。

--sockopts

覆盖了 rsyncd.conf 文件中 socket options 字段的设置,并具有相同的语法。

见 client 版本的 --sockopts 选项。

--verbose, -v

增加了 daemon 在启动阶段记录的信息量。在客户端连接后,daemon 输出的信息的详细程度将由客户端使用的选项和模块配置部分中的 max verbosity 设置来控制。

见 client 版本的 --verbose 选项。

--ipv4, -4 或 --ipv6, -6

rsync daemon 监听连接的传入套接字时优先使用 IPv4 或 IPv6。在较旧版本的 Linux 中,可能需要其中一个选项来解决内核中的 IPv6 错误: 如果在没有其他进程使用该端口的情况下出现 "address alrady in use" 的错误,请尝试启动 daemon 时指定 --ipv6--ipv4

见 client 版本的 --ipv4, -4--ipv6, -6 选项。

注意,如果 rsync 在编译时不支持 IPv6,则 --ipv6 选项将不起作用。 rsync --version 输出将显示 "no IPv6"。

--help, -h

--daemon 之后使用时,输出一个简短的帮助页面,描述启动 rsync daemon 可用的选项。

19. 过滤规则

过滤规则允许自定义文件被如何处理:

  • 控制发送端将哪些文件放入描述传输层次结构的文件列表中 (哪些文件进入传输列表)
  • 控制接收端保护哪些没有出现在发送端传输列表中的文件,避免文件被删除
  • 控制复制 xattrs 属性时跳过哪些扩展属性字段

这些规则可以通过直接指定选项的参数来定义,也可以从一个或多个文件中读取。过滤规则文件甚至可以是被复制文件层次结构的一部分,在不同的目录层级中以不同方式影响整个树结构。

19.1. 简单的 include/exclude 规则

首先介绍包含 (include) 和排除 (exclude) 规则对文件传输的基本影响,忽略任何删除的副作用。过滤规则主要影响 rsync 递归扫描时被扫的目录及其内容,但这些规则也可以影响作为参数指定的传输中的顶级条目。 译者注: 比如,指定了两个 SRC 目录,但是被规则排除了一个。

对于任何未被匹配到的文件或目录,默认情况下会被包含在传输中,并将该文件或目录添加到发送端的传输列表中。使用排除规则会导致一个或多个匹配的文件或目录从发送端的传输列表中被排除。可以使用 include 规则来限制 exclude 规则匹配过多文件产生的影响。

规则的顺序很重要,因为第一个匹配的规则生效。因此,如果一个早期规则将一个文件排除,后面的 include 规则将不会起任何作用。这意味着用户必须在 exclude 规则之前放置所有的 include 规则,以限制其作用的范围。 译者注: 作者的意思是,必须把 include 规则放在 exclude 规则之前,以保证所有被 include 规则匹配到的文件不被 exclude 规则排除。

当一个目录被排除时,它的所有内容和子内容也会被排除。发送端不会扫描这个被排除的目录中的任何内容,这在跳过大型不需要的子目录时可以节省很多时间。

include 和 exclude 规则适用于发送端要递归扫描的每个文件和目录。因此,如果想要包含特定的深层文件,必须确保在扫描到到该文件所在深度的过程中没有排除过程中必须遍历的目录,否则该文件将永远不会被发现,也就不会进入传输列表。举个例子,如果目录 a/path 被指定为传输参数,而用户希望文件 a/path/down/deep/wanted.txt 是传输的一部分,那么发送方不能将目录 a/path, a/path/down 或 a/path/down/deep 排除在扫描范围外,因为这样做会让 rsync 的扫描过程无法到达该文件所在的深度。

当用户处理规则时,向 rsync 询问被 include 或 exclude 的文件以及原因,可能会有所帮助。通过指定 --debug=FILTER 或 (在拉取文件时) -M--debug=FILTER ,可以打开 FILTER 调试信息的 1 级输出。rsync 将在每次 include 或 exclude 文件或目录时,输出一条消息。消息包含被 include 和/或 exclude 的文件或目录,以及是哪条匹配规则导致了当前的 include/exclude。从 v3.2.4 开始,如果过滤规则尾部存在空白字符,它还会发出警告,因为带有尾部空格的 exclude 规则 "foo " 不会排除名为 "foo" 的文件。

include 和 exclude 规则可以使用通配符模式匹配 (类似于 shell 通配符),允许匹配文件后缀或文件名的一部分。

通过在文件名后添加斜杠,可以将规则限制为仅影响目录。

19.2. 简单的 include/exclude 例子

在发送端创建以下文件树:

mkdir x/
touch x/file.txt
mkdir x/y/
touch x/y/file.txt
touch x/y/zzz.txt
mkdir x/z/
touch x/z/file.txt

译者注: 就是这样的

root@freebsd:~ # tree x
x
├── file.txt
├── y
│   ├── file.txt
│   └── zzz.txt
└── z
    └── file.txt

3 directories, 4 files

接下来的 rsync 命令将传输文件 x/y/file.txt 和所需的目录,使得在远程主机上存在路径 /tmp/x/y/file.txt :

rsync -ai -f'+ x/' -f'+ x/y/' -f'+ x/y/file.txt' -f'- *' x host:/tmp/

译者注: 这个写法没啥特别的,就是穷举法,用 include 包含 x/y/file.txt 涉及到的每级目录与文件,然后用 exclude 规则排除所有文件。

此外,这个复制也可以使用 -R 选项完成 (尽管如果启用了删除功能,这两个命令的行为会有所不同):

rsync -aiR x/y/file.txt host:/tmp/

译者注: -R 选项启用相对路径,在 host:/tmp 目录下建立 SRC 路径字符串中指定的路径。

下面的命令不需要 include x 目录,因为 x 目录不是传输的一部分 (注意尾部斜杠)。运行这个命令会只复制 /tmp/x/file.txt,因为 y 和 z 目录被排除在外:

rsync -ai -f'+ file.txt' -f'- *' x/ host:/tmp/x/

译者注: 注意,这个命令复制的是 x/file.txt 不是 y 或 z 目录中的 file.txt 文件。

下面的命令在复制 x 目录及其所有内容时会省略 zzz.txt 文件:

rsync -ai -f'- zzz.txt' x host:/tmp/

19.3. 删除文件时的 filter 规则

默认情况下,include 和 exclude 规则同时影响发送端 (创建传输列表) 和接收端 (创建用于计算哪些文件要被删除的文件列表)。如果没有启用删除选项,接收端会跳过创建与删除相关的文件列表。可以手动覆盖这个默认作用于两端的设置,这样用户可以仅指定发送方规则或接收方规则,详见下一节 filter 规则深入解析

做删除操作时,exclude 规则可以保护接收方的文件不被删除,而 include 规则会覆盖这种保护 (将文件置于可能被删除的风险中)。默认情况下,文件处于风险状态,其安全性取决于它是否与发送方的相应文件匹配。

作用于两端的 exclude 规则的示例是,在两个系统之间复制一个 C 开发目录。在传输这个目录时,用户可能希望跳过复制已构建的可执行文件和 .o 文件 (发送端隐藏),以便接收端可以自行构建它们,并且不会丢失任何已经构建的 .o 文件 (接收端保护)。例如:

rsync -ai --del -f'- *.o' -f'- cmd' src host:/dest/

译者注: 注意上面写的两个 filter 在发送端和接收端都起作用。但是单排除 .o 文件的话 -f'- *.o' 就够用,我没搞明白 -f'- cmd' 是在排除什么。

请注意,如果目录结构可能发生变化,使用 -f'-p *.o' 比 -f'- *.o' 更好。 p 修饰符在 filter 规则修饰符 一节中有讨论。

最后需要注意的是,如果 shell 不会在遇到未匹配的通配符时出现问题,可以通过在空格处使用下划线并省略引号来简化过滤选项的输入。例如,可以使用 -f -_*.o -f -_cmd (以及类似的方式) 来代替上面的过滤选项。

19.4. filter 规则深入解析

rsync 支持旧式的 include/exclude 规则和新式的过滤规则。旧式规则使用 --include--exclude ,以及 --include-from--exclude-from 来指定。这些规则在行为上有所限制,但它们不需要 -+ 前缀。旧式 exclude 规则会转换为 - <name> 过滤规则 (没有修饰符),而旧式 include 规则会转换为 + <name> 过滤规则 (没有修饰符)。 译者注: 就是旧式的规则会被转成新式的规则。

rsync 根据在命令行上指定的顺序,以及从文件中读取的规则构建一个有序的过滤规则列表。新式过滤规则的语法如下:

RULE [PATTERN_OR_FILENAME]
RULE,MODIFIERS [PATTERN_OR_FILENAME]

可以选择使用短或长的规则名称,如下所述。如果使用短命名规则,则分隔规则与修饰符的逗号是可选的。紧随其后的 PATTERN_OR_FILENAME (如果存在) 必须在单个空格或下划线 (_) 后面。任何额外的空格和/或下划线都被视为模式名称的一部分。以下是可用的规则前缀 (RULE,MODIFIERS [PATTERN_OR_FILENAME] 中的 RULE):

exclude, '-'

指定一个 exclude 规则的匹配模式,默认情况下,exclude 是 hide 和 protect。

include, '+'

指定一个 include 规则的匹配模式,默认情况下,include 是 show 和 risk。

merge, '.'

指定一个 client 侧的 merge-file 来读取更多的规则。

dir-merge, ':'

指定每个目录的 merge-file。使用这种类型的过滤规则需要信任发送端的 filter 检查,因此会有 --trust-sender 选项中提到的副作用。

hide, 'H'

指定一个过滤规则的匹配模式,用于在传输中隐藏文件。等于只在发送端起作用的 exclude 规则,所以 -f'H foo'-f'-s foo 有相同的语义。 译者注: -f'-s foo 中的小写 s 是过滤器修饰符。

show, 'S'

被匹配模式匹配到的文件不会被隐藏。等于只在发送端起作用的 include 规则,所以 -f'S foo'-f'+s foo' 有相同的语义。 译者注: -f'+s foo 中的小写 s 是过滤器修饰符。

protect 'P'

指定保护文件不被删除的匹配模式。等于只在接收端起作用的 exclude,所以 -f'P foo-f'-r foo' 有相同的语义。/译者注: -f'-r foo 中的小写 r 是过滤器修饰符。/

risk, 'R'

被匹配模式匹配到的文件不会被保护 (可能会被删除)。等于之在接收端起作用的 include,所以 -f'R foo-f'+r foo' 有相同的语义。/译者注: -f'+r foo 中的小写 r 是过滤器修饰符。/

clear, '!'

清除目前所有的 include/exclude 规则列表 (不带参数)。

当从文件中读取规则 (使用 merge 或 dir-merge) 时,空行将被忽略/以 # 开头行按注释处理,被忽略。包含 # 的文件名规则不受影响。

还要注意, --filter, --include--exclude 选项每次只接受一个规则/匹配模式。要添加多个规则,可以在命令行上重复使用这些选项,使用 --filter 选项的 merge-file 语法,或使用 --include-from / --exclude-from 选项。

19.5. 模式匹配规则

上面提到的大多数规则都带有一个参数,用于指定规则应匹配的内容。如果 rsync 正在递归遍历目录的层次结构,记住,每个匹配模式将与 rsync 发现的文件名所在路径字符串中的每个目录名进行匹配。

译者注: 以 / 开头的匹配模式指定的根路径是 SRC 的路径字符中指定的路径,并不是文件系统的 / 路径。

模式参数的匹配规则有几种形式:

  • 如果模式包含斜杠 / (不包括路径尾部的斜杠) 或 ** (可以匹配斜杠),则模式将与完整的路径名匹配,包括传输中的任何前导目录。如果模式不包含 (非尾部的) /** ,则只会与文件名或路径名的最后一级匹配。例如,foo 表示路径字符串的最后一级必须为 foo ,而 foo/bar 则会匹配路径的最后两个元素,只要这两个元素都在传输范围内。 译者注: ** 匹配 0 或多个任意字符。
  • / 结尾的模式只匹配目录,不匹配普通文件、符号链接和设备。
  • / 开头的模式与传输路径的开头相匹配,而不是末尾。例如,/foo/** 或 foo/bar/** 只匹配路径中的前导元素。如果规则从每个目录的过滤文件中读取,则被匹配的传输路径将从过滤文件的级别开始,而不是传输的顶层。有关如何指定在传输根目录匹配的模式的完整讨论,见 锚定 include/exclude 模式 一节。 /译者注: 通常,以 / 开头的路径匹配模式的根路径是 SRC 指定的目录。但如果每个目录有自己的过滤规则文件,那么,每个过滤规则文中的过滤规则的匹配模式的根路径,是滤规则文件所在的目录。

rsync 根据模式中是否包含 *, ?[ 这三个通配符字符之一来选择进行简单字符串匹配还是通配符匹配:

  • ? 匹配除斜杠 / 外的任何字符一次。
  • * 匹配除斜杠 / 外的任何字符 0 或多次。
  • ** 匹配任何字符 0 或多次。
  • [ 引入了一个字符类。比如 [a-z][[:alpha:]]: 必须匹配一个字符。
  • 在模式中的末尾使用 *** 是一种简写形式,允许使用一个单独的规则匹配一个目录及其所有内容。例如,指定 dir_name/*** 将匹配 dir_name 目录 (就像指定了 dir_name/ 一样),以及该目录中的所有内容 (就像指定了 dir_name/** 一样)。
  • 反斜杠可以用于转义通配符符,但只有在模式字符串中至少包含一个通配符时,它才被解释为转义字符。例如,模式 foo\bar 不包含通配符,反斜杠依旧按反斜杠处理;而模式 foo\bar* 因为包含通配符星号 *~,所以需要改为 ~foo\\bar* 以避免 \b 被错误地转义。

下面是一些使用 exclude/include 规则的匹配模式的例子:

  • -f'- *.o' 排除所有以 .o 结尾的文件。
  • -f'- /foo' 在传输的顶层目录 (就是 SRC 的路径字符串指定的目录) 中,排除名为 foo 的文件,或名为 foo 的目录。
  • -f'- foo/' 排除所有名为 foo 的目录。
  • -f'- foo/*/bar' 排除所有名为 bar 的,在 foo 的第二级子目录下的,文件或目录。
  • -f'- /foo/**/bar' 排除任何位于名为 foo 的顶级目录下的,第二级或更多级别子目录中名为 bar 文件或目录。注意 /foo/bar 不会被排除。
  • -f'+ */' -f'+ *.c' -f'- *' 包含所有目录和 .c 源文件,但不包含其他内容。
  • -f'+ foo/' -f'+ foo/bar.c' -f'- *' 仅包含 foo 目录和 foo/bar.c (foo 目录必须明确地包含,否则它将被 - * 规则排除)。

19.6. filter 规则的修饰符

指定 include (+) 或 exclude (-) 规则之后,可以使用以下修饰符:

  • / 让 include/exclude 规则应与当前项目的绝对路径名匹配。例如:
    • -f'-/ /etc/passwd 会在传输 /etc 目录时排除 passwd 文件
    • -f'-/ subdir/foo' 始终排除父目录名为 subdir 的 foo 目录。另外,注意,即使 foo 目录是当前传输的根目录,foo 也会被排除
  • ! 表示如果模式匹配失败,则应用 include/exclude规则。例如 -f'-! */' 将排除所有非目录项。 译者注: 就是对匹配结果取非。
  • C 表示所有的全局 CVS exclude 规则应该被插入为排除项,代替 -C 选项。不需要任何参数。
  • s 让规则应用于发送端。当规则影响发送端时,规则会影响哪些文件被放入发送端的传输列表。默认情况下,规则会影响双方,除非指定了 --delete-excluded 选项,这样默认规则就只适用于发送方。此外,还有 hide 规则 (H) 和 show 规则 (S),它们是指定发送端 include/exclude 规则的另一种方式。
  • r 让规则应用于接收端。当规则影响接收端时,它阻止文件被删除。详见 s 修饰符。此外,还有 protect 规则 (P) 和 risk 规则 (R),它们是指定接收端 include/exclude 规则的另一种方式。
  • p 表示规则是 perishable (易腐败?) 的,意味着目录中在正在删除的内容会被忽略。例如, --cvs-exclude (-C) 选项的默认规则会排除类似 "CVS" 和 "*.o" 的内容,这些内容被被标记为 perishable,并且不会阻止在发送端被删除的目录在接收端被删除。 译者注: 这段我没咋读懂,但是我尽量意译了。
  • x 指明了在 xattr 复制/删除操作中影响 xattr name 的规则 (在匹配文件/目录名时被忽略)。如果没有指定可以匹配 xattr 的规则,则使用默认的 xattr 过滤规则 (见 --xattrs 选项)。

19.7. merge-file filter 规则

可以通过指定 merge (.) 或 dir-merge (:) 过滤规则将包含过滤规则的整个文件合并到用户的过滤规则中 (如上文所介绍的那些规则)。

合并文件有两种类型 -- single-instance 单实例 (.) 和 per-directory 每个目录 (:)。单实例合并中,文件只被读取一次,并且文件中的规则将在当前过滤列表中代替 "." 规则。 译者注: 以 . 开头的规则是加载一个规则文件的命令,当文件被加载之后,这个加载文件的规则就被删除了。 对于每个目录的合并文件,rsync 扫描它遍历的每个目录以查找指定的规则文件,当用户指定的规则文件存在时,将其内容合并到当前继承规则的列表中。每个目录的规则文件必须在发送端创建,因为是发送端要扫描查找可被传输的文件,而不是接收端。如果用户希望受规则文件中的规则影响的某些文件不被删除,可能还需要将这些规则文件传输到接收端 (见 per-directory 的规则与文件的删除 一节)。

例子:

merge /etc/rsync/default.rules
. /etc/rsync/default.rules
dir-merge .per-dir-filter
dir-merge,n-	.non-inherited-per-dir-excludes
:n- .non-inherited-per-dir-excludes

译者注: 上面的那些例子在选项里的完整写法应该是 -f'merge /etc/rsync/default.rules', -f'. /etc/rsync/default.rules' 等。上面的例子少加了 -f'' 。默认情况下 include 于 exclude 作用于收发两端,被发送端 exclude 的文件不会在接收端被删除。

在 merge 或 dir-merge 规则名之后,可以使用以下修饰符:

  • - 指定的规则文件应只包含 exclude 匹配规则,文件内还可以有注释。
  • + 指定的规则文件应只包含 include 匹配规则,文件内还可以有注释。
  • C 是一种指定文件应以与 CVS 兼容的方式进行读取的方式。这个修饰符隐含了 n, w- 修饰符,但也允许指定列表清除修饰符 (!)。如果没有在参数部分提供文件名,则假定为 ".cvsignore"。
  • e 表示从传输中排除被 merge 的规则文件。例如 dir-merge,e .rules 相当于 dir-merge .rules- .rules 规则的合并。
  • n 表示规则不会被子目录继承。
  • w 表示规则在空白字符上进行单词拆分,而不是正常的行拆分。这也会关闭注释。注意: 将前缀与规则分开的空格会被特殊处理,所以 "- foo + bar" 被解析为两个规则 (假设前缀解析没有被禁用)。
  • 还可以指定 +- 规则中的任何修饰符,以便从文件中读取的规则默认具有该修饰符 (除了 ! 修饰符,它没有用)。 译者注: 意思是还能用 filter 规则修饰符 一节中提到的规则修饰符。 例如 merge,-/ .excl 将把 .excl 的内容视为绝对路径排除项,而 dir-merge,s .filt:sC 将使每个目录中的规则文件都仅适用于发送端。如果合并规则指定要影响的方向 (通过 s 或/和 r 修饰符),则文件中的规则不能通过修饰符或规则前缀指定方向,例如文件中的规则中不能使用 hide 指定方向。

除非使用 n 修饰符,否则应用于目录的规则会被其所有子目录继承。每个子目录的规则会被添加到父目录的规则之前,这使得最新的规则比继承的规则优先级更高。整个 dir-merge 规则集在指名规则文件的位置被分组。 译者注: 比如 rsync 命令中指定了两个 dir-merge -f'dir-merge .file1' -f'dir-merge .file2' ,那么此时有两个 dir-merge 的规则组,并且从 .file1 解析出来的规则组的优先级高于从 .file2 解析出来的规则组。 因此可以通过在全局规则列表中,指定先于 dir-merge 规则来覆盖 dir-merge 的规则。当从每个目录下的规则文件中读取清除规则列表的规则 (!) 时,它只会清除当前规则列表中的继承规则。 译者注: 从一个目录下读取规则文件,读到清除规则列表的规则 ! 时,只会清除它从父目录继承来的规则。比如在各级目录解析 .file1 规则文件的时候,解析到了 ! ,那就只把该目录从父目录继承来的,各级父目录从 .file1 中生成的规则给清掉,并不会清从 .file2 解析来的规则。

另一种防止从 dir-merge 规则文件中继承规则的方法是使用前导斜杠将其锚定。如果每个目录都有其自己的规则文件,那么这些规则文件中的规则的锚点是这些文件本身所处的目录。因此,如果规则文件中有匹配模式 "foo",那么 rsync 只能匹配到写有该匹配模式的文件的所在目录中的名为 "foo" 的文件。 /译者注: 写成 "/foo" 就是匹配写有该匹配模式的文件的所在目录中的名为 "foo" 的目录。/

下面是通过 --filter=". file" 选项指定使用单实例 (.) 的方式加载名为 file 的规则文件中规则的例子。名为 file 的文件的内容如下:

merge /home/user/.global-filter
- *.gz
dir-merge .rules
+ *.[ch]
- *.o
- foo*

上面的命令和文件的效果是,先把规则文件 /home/user/.global-filter 中的规则合并到规则列表的开头 (就是前面提到的 single-instance merge 单实例合并的方式);排除所有以 .gz 结尾的文件;在每个目录下查找名为 .rules 的文件,将其以 per-directory merge 的方式加载文件中的规则;往后的行就和第二行一样,都是普通的 include/exclude 规则了。在开始扫描目录之前读取的所有规则都遵循全局锚定规则 (例如,前导斜杠表示的根路径是 SRC 的路径字符串指定的路径)。

如果使用 per-directory merge 方式的规则文件的路径是第一个传输目录的父目录 (译者注: 不论是第几级父目录) ,rsync 将从规则文件所在位置为起始点,向下扫描所有的规则文件。例如,这是一个常见的过滤器 (参见 -F 选项):

--filter=': /.rsync-filter'

译者注: 下面这段原文用的语法有点怪,看不懂,我自己重写了。

该规则告诉 rsync 从 / 目录开始扫描并解析 .rsync-filter 规则文件,而不是从 SRC 的路径字符串指定的目录开始处理。注意: 对于 rsync daemon 来说, --filter=': /.rsync-filter' 中的 / 目录始终与模块的 path 相同。

下面是一些例子,前两条会扫描 SRC 指定的路径的父目录中的规则文件,后一条不会扫描父目录中的规则文件:

rsync -avF /src/path/ /dest/dir
rsync -av --filter=': ../../.rsync-filter' /src/path/ /dest/dir
rsync -av --filter=': .rsync-filter'	/src/path/ /dest/dir

译者注: 下面这段,文档原文写的不是很容易理解,我自己重写了。注意比对原文。

第一行命令中的 -F 选项是 -f': /.rsync-filter' 的简写,该命令会从 / 目录开始扫描并解析 .rsync-filter 规则文件。第二行命令中,扫描 .rsync-filter 规则的基准路径是 src/path,需要综合 --filter 选项的参数值指定的路径,得到 ~/src/path../../.rsync-filter~ ,化简得到 /.rsync-filter 。可以看到,还是从 / 目录开始扫描并解析 .rsync-filter 规则文件。前两条命令都是从 / 开始扫描并解析规则文件,这意味着 / 目录下和 /src 目录下的规则文件都会被扫描并解析。第三条命令就不会扫描父目录中的规则文件了,命令中的 --filter 选项的参数没有带路径,所以 rsync 会扫描 SRC 指定的目录中的每个目录下的 .rsync-filter 文件。

如果用户想在匹配模式中包含 ".cvsignore" 的内容,可以使用规则 -f':C' ,它会创建一个 dir-merge 的 .cvsignore 文件,并按照与 CVS 兼容的方式解析。可以使用这个规则来影响 --cvs-exclude (-C) 选项中将每个目录的 .cvsignore 文件包含在规则中的位置,只需添加过滤规则 -f':C' 即可。如果没有这样做,rsync 将把 .cvsignore 文件的 dir-merge 规则添加到所有其他规则的末尾 (这意味着它的优先级低于命令行指定的规则)。比如:

cat <<EOT | rsync -avC --filter='. -' a/ b
+ foo.o
:C
- *.old
EOT

rsync -avC --include=foo.o -f :C --exclude='*.old' a/ b

上面两个 rsync 命令的行为相同。每个命令都会在规则列表中合并所有的 per-directory .cvsignore 规则,而不是在末尾。这允许它们的每个目录特定的规则取代 -f':C' 的规则,而不是服从所有规则。如果想影响其他 CVS 排除规则 (即默认的排除列表,$HOME/.cvsignore 文件的内容和 $CVSIGNORE 变量的值),应该省略 -C 命令行选项,并在过滤器规则中插入一个 -C 规则,例如 --filter=-C

19.8. 清理规则列表的 filter 规则

可以通过使用 ! 过滤规则来清除当前的 include/exclude 列表。当前的规则列表可以是全局规则列表,也可以是每个目录自己的一组规则。

在解析 rsync 命令中遇到的 filter 选项时生成的规则是全局规则。每个目录可以有自己的规则,但是目录的子目录会继承父目录的过滤规则,所以在处理子目录的过滤规则时可以先用这个过滤规则来清理父目录的过滤规则。

19.9. 锚定 include/exclude 模式

如前所述,全局的 include/exclude 模式是以 传输的根目录 ("root of the transfer") 为锚点 (per-directory 模式的锚点是每个规则文件所在的目录)。如果将传输内容视为从发送端到接收端发送的名称的子树,则传输内容的根目录是树在目标目录中开始复制的位置。这个根目录决定了以 / 开头的模式匹配的位置。

因为模式匹配是相对于传输的根目录的,所以,更改源路径的尾部斜杠,或使用 --relative 选项会影响匹配模式中使用的路径 (除了更改 DEST 上复制的文件树的数量外)。以下示例演示了这一点。

假设要匹配两个源文件,一个绝对路径为 "/home/me/foo/bar",另一个路径为 "/home/you/bar/baz"。以下是针对在使用两个 SRC 字段的情况下在传输时不同命令选择的区别:

Example cmd: rsync -a /home/me /home/you /dest
+/- pattern: /me/foo/bar
+/- pattern: /you/bar/baz
Target file: /dest/me/foo/bar
Target file: /dest/you/bar/baz

Example cmd: rsync -a /home/me/ /home/you/ /dest
+/- pattern: /foo/bar               (路径中去掉了 "me")
+/- pattern: /bar/baz               (路径中去掉了 "you")
Target file: /dest/foo/bar
Target file: /dest/bar/baz

Example cmd: rsync -a --relative /home/me/ /home/you	/dest
+/- pattern: /home/me/foo/bar       (使用完整路径)
+/- pattern: /home/you/bar/baz      (使用完整路径)
Target file: /dest/home/me/foo/bar
Target file: /dest/home/you/bar/baz

Example cmd: cd /home; rsync	-a --relative me/foo you/ /dest
+/- pattern: /me/foo/bar            (从指定路径开始)
+/- pattern: /you/bar/baz           (从指定路径开始)
Target file: /dest/me/foo/bar
Target file: /dest/you/bar/baz

最简单的方法是查看使用 --verbose 选项输出的内容,并在名称前面加上 /。如果还不准备复制任何文件,需要使用使用 --dry-run 选项。

19.10. per-directory 的规则与文件的删除

译者注: 我读了好几遍讲规则文件的这 2 节,作者似乎想表达的意思是,在 client 端命令行中直接写明的过滤规则会被直接发送到 server 端的 rsync 进程;如果 client 端命令行指定的是全局规则文件 (使用 merge 过滤模式的规则文件的地址) 的地址,那么被解析出的全局过滤规则也会被直接发送到 server 端的 rsync 进程;如果 client 端命令中写的是使用 dir-merge 过滤模式的规则文件的地址,不论这些规则文件是否被传输到了 server 端,只要 client 用了 dir-merge 过滤模式,server 端都就自己去 server 端的对应地址上找对应名字的规则文件。

没有删除选项时,每个目录的规则只影响发送端,因此可以自由地排除规则文件而不影响传输。为了使此过程更加简单,修饰符 e 会自动排除规则文件,如下两个等效的命令所示:

译者注: 在没有删除选项时,接收端不需使用过滤规则来构建删除列表。所以说,不删除文件时,规则不影响接收端,只影响发送端。

rsync -av --filter=': .excl'	--exclude=.excl	host:src/dir /dest
rsync -av --filter=':e .excl' host:src/dir /dest

然而,如果要在接收端执行删除操作,并且希望 exclude 某些文件使其不被删除,需要确保接收方知道要排除哪些文件。最简单的方法是在传输中包含每个目录的规则文件并使用 --delete-after 选项,这可以确保接收端在尝试删除任何文件之前获得与发送端相同的所有 exclude 规则:

rsync -avF --delete-after host:src/dir /dest

译者注: 命令中有删除选项意味着,接端方需要构建删除列表。选项 -F 展开后是 --filter='dir-merge /.rsync-filter' ,这个选项指定了规则文件。这意味着 rsync 从 / 目录开始递归查找 .rsync-filter 规则文件,所有找到的 .rsync-filter 规则文件都会生效,但是只有 SRC 指定的路径及其子路径中的 .rsync-filter 规则文件会被发送到接收端的对应位置。

译者注: 默认情况下,被发送端 exclude 的文件不会在接收端被删除。

然而,如果规则文件不是传输的一部分,就需要在命令行上指定一些全局 exclude 规则 (就是下面例子中的 --filter='. /my/extra.rules'),或者需要在接收端维护自己的每个目录的规则文件。第一个示例如下 (假设 remote host 上的 .rules 文件排除了自身):

rsync -av --filter=': .rules' --filter='. /my/extra.rules'
          --delete host:src/dir /dest

译者注: 上面的例子中提到 remote host 上的 .rules 规则文件在其内部的规则中排除了 .rules 自身,所以使用 dir-merge 过滤模式的 .rules 文件不会被传输到接收端上。所以,接收端没有发送端发来的规则文件,就没有构建删除列表的依据。但删除操作还是要做,所以,另外给了一个全局规则文件 /my/extra.rules,这个文件里面是专门给接收端使用的过滤规则。

上面例子中的 extra.rules 文件可以影响传输的双方,但是这条规则放在 per-directory merge 的规则的后面,所以,当 --filter=': .rules'--filter='. /my/extra.rules' 有冲突时,选项 --filter=': .rules' 中的规则会生效,因为它在前面。

译者注: 另一个方法是,在接收端的每个目录中维护一份规则列表,就像下面这段说的。

最后一个例子。remote 端从传输中排除了 .rsync-filter 文件,用户想要使用自己的 .rsync-filter 文件来控制接收端的删除行为。为了做到这一点,必须明确地在发送端排除采用 dir-merge 过滤模式的规则文件 (并且以防止接收端上对应的规则文件被改变),然后将规则放入本地文件中以控制其他不应该被删除的内容。就像下面的两个命令中的一个:

rsync -av --filter=':e /.rsync-filter' --delete host:src/dir /dest

rsync -avFF --delete host:src/dir /dest

译者注: 第一条命令中的 e 修饰符在发送端排除了被使用的规则文件。第二条命令的 -FF 规则展开后是 --filter='dir-merge /.rsync-filter' --filter='exclude .rsync-filter' ,效果也是在发送端排除了被使用的规则文件。但是发送端确实又使用了 dir-merge 过滤模式,所以 server 端的 rsync 就只能在 server 端本地的接收目录中找 .rsync-filter 文件,然后就找到了用户自定义的 .rsync-filter 文件。

20. 传输规则

filter rules 会在发送端影响生成文件列表时的递归扫描,在接收端影响文件删除之外,transfer rules 也一样。传输规则影响哪些文件需要传输,而不受排除过滤规则的影响。传输规则只影响文件,而不影响目录。

由于传输规则不影响发送端和接收端的文件列表,因此它也无法影响接收端要删除哪些文件。例如,如果文件 "foo" 存在于发送端的列表中,但被传输规则忽略 (存在根据文件大小忽略文件的规则),则接收端不会请求该文件。但是,它在文件列表中就意味着,接收端删除文件的过程中不会删除 "foo" 文件。另一方面,对文件 "foo" 进行 server 端排除 (hide) 会将该文件从 server 的文件列表中去除,除非接收端排除 (protect) 它,否则,如果请求了删除,接收端将删除匹配的文件名为 "foo" 的文件。

考虑到文件仍在发送端的文件列表中,即使某个目录只包含了被传输规则忽略的文件,选项 --prune-empty-dirs 依旧不会将该目录判断为空。

同样地,传输规则对于接收端删除哪些文件也没有额外的影响,因此设置传输的最大文件大小并不能阻止大文件被删除。

译者注: 上面那段,我猜,作者可能是想说,设置了可以传输的最大的文件大小之后,接收端不会把超过大小限制的文件放进传输列表。接收端收到的传输列表中,也没有超过大小限制的文件。那么接收端已经存在的,超过大小限制的,不在传输列表中的文件会被删除。前提是使用了 --delete 选项。

传输规则的例子包括默认的 quick check 算法 (比较文件大小和修改时间)、 --update 选项、 --max-size 选项、 --ignore-non-existing 选项以及其他一些选项。

21. 批处理模式

批处理模式可以用于将相同的更新应用于许多相同的系统。假设有个目录要被复制到多个主机上。现在,对这个源目录做了一些更改,并且这些更改需要同步到其他主机。为了使用批处理模式实现这一点,可以使用 --write-batch 选项将对源目录所做的更改应用到接收端的一个主机。 --write-batch 选项会导致 rsync client 将执行此操作所需的所有信息存储在一个 batch file 中,以便在其他的主机上重复此操作。

生成 batch file 可以避免在更新多个主机上的目录时多次执行检查文件状态、产生校验和、生成数据块等操作。广播传输协议可以用于同时将用于更新目录的 batch file 并行传输到多个主机,而不是将相同的数据单独发送给每个主机。这样可以提高更新效率,节省带宽和时间。

要将 batch file 中记录的更改情况应用于另一个主机的目标目录,使用 --read-batch 选项,指定相同的 batch file 和目标主机及其上目录的名称。rsync 将使用 batch file 中存储的信息来更新目标主机上的目录。这样可以快速而有效地将更改应用到多个相同的目标树中。

方便起见,使用 --write-batch 选项时,还会创建一个脚本文件,其名称与 batch file 相同,后面附加 ".sh"。该脚本文件包含一个适用于使用相关 batch file 更新目标主机上的目录的命令行。可以在目标主机上使用 bash 或其他兼容的 shell 来执行它,还可以为这个 .sh 脚本传入目标主机上的目标路径的字符串,该字符串表示的路径将代替生成 .sh 文件时使用的目标路径。这在目标主机上要被更新的目录的路径,与创建 batch file 的主机上的目标目录的路径不同时,很有用。比如:

rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
scp foo* remote:
ssh remote ./foo.sh /bdest/dir/

rsync --write-batch=foo -a /source/dir/ /adest/dir/
ssh remote rsync --read-batch=- -a /bdest/dir/ < foo

译者注: 上面的命令会生成一个 foo 文件,一个 foo.sh 文件。foo 文件里存储了要被更新的数据与更新数据的方法,这意味着,所有在本次 rsync 命令中被传输的数据都会保存在 foo 文件中。所以,一旦被更新的数据较多,foo 文件的大小也会极大。foo.sh 文件里只存储了一条 rsync 命令,这个文件很小,也很好理解。

在这些示例中,rsync 被用于根据 /source/dir 更新 /adest/dir,并将重复此操作所需的信息存储在 foo (batch file) 和 foo.sh 中。然后使用 batch file 中的数据更新 remote 主机上的数据,remote 主机上的要被更新的数据存储在目录 /bdest/dir 中。这两个示例之间的差异揭示了处理批处理时的一些灵活性:

  • 第一个示例展示了初始复制并不一定要在本地进行,用户可以使用 remote 主机的 remote shell 语法或 rsync daemon 语法来 push 或 pull 数据,根据需要选择。
  • 第一个示例在 remote 主机上运行 read-batch 命令时,使用 remote 主机上的 foo.sh 文件来获取正确的 rsync 选项。
  • 第二个示例通过标准输入读取批处理数据,因此不需要先将 batch file 复制到 remote 主机。这个示例不使用 foo.sh 脚本,因为它需要使用修改后的 --read-batch 选项,但是如果用户想要使用 foo.sh 脚本,则可以编辑脚本文件。另外,这种用法需要确保没有其他选项尝试使用标准输入,比如 --exclude-from=- 选项。

警告:

--read-batch 选项期望正在更新的目标目录与用于创建 batch file 的目录在被更新前完全相同。当要被更新的目录与用于创建 batch file 的目录被更新前的状态有差异时,如果文件看起来已经是最新的,那么更新可能会被丢弃并显示警告;或者会尝试文件更新,然后如果文件被处理后未能通过验证,则会出现错误并丢弃更新。这意味着如果命令被中断,重新运行 --read-batch 操作是安全的。如果希望无论文件的大小和日期如何都始终尝试进行批量更新,请使用 -I 选项 (在读取 batch file 时使用)。如果发生错误,目标目录可能处于部分更新状态。在这种情况下,可以使用 rsync 的常规 (非 batch) 模式来修复目标目录。

所有运行 ~--read-batch~ 的 rsync 版本必须大于等于生成 batch file 的 rsync 的版本。如果 batch file 中的 batch protocol 版本对于运行 --read-batch 的 rsync 来说太新,运行 --read-batch 的 rsync 会报错并退出。见 --protocol 选项以了解如何让创建 batch file 的 rsync 生成一个旧版 rsync 可以理解的 batch file。注意,batch file 在 v2.6.3 中更改了格式,因此将低于此版本的 rsync 与高于此版本的 rsync 将无法协同工作。

读取 batch file 时,rsync 命令使用的某些参数的值如果没有与创建 batch file 时使用的命令的参数值相匹配,rsync 将强制这些特定选项的值与 batch file 中的数据匹配。其他选项可以,而且应该被更改。例如 --write-batch 被更改为 --read-batch--files-from 选项被删除,并且 --filter / --include / --exclude 选项只有在指定了 --delete 相关选项之一时才需要。

创建 BATCH.sh 文件的代码将任何 filter/include/exclude 选项转换为一个单独的列表,并将其作为 here 文档附加到 shell 脚本文件中。高级用户可以使用此功能修改排除列表,以便更改被 --delete 选项删除的内容。普通用户可以忽略此细节,只需使用 shell 脚本作为运行 --read-batch 命令的简便方法来处理 batch file 即可。

原始的 rsync batch 模式基于 "rsync +",但最新版本使用了新的实现。

22. 符号链接

rsync 在 SRC 中遇到符号链接时有三种基本行为。

默认情况下,符号链接根本不会被传输。对于任何存在的符号链接,将会发出一条 "skipping non-regular" 的消息。

如果指定了 --links 选项,那么符号链接将被添加到传输列表中 (而不是被忽略),并且默认处理方式是在目标上重新创建具有相同目标的符号链接。注意, --archive 选项暗示了 --links 选项。

如果指定了 --copy-links 选项,那么符号链接会被解引用。即复制符号链接指向的目标,而不是复制符号链接本身。换句话说,会将符号链接转换成实际的目标文件或目录进行传输。

rsync 还可以区分 safe 和 unsafe 的符号链接。一个可能使用这种区分的例子是网站镜像,用户希望被复制的 rsync 模块不包含指向站点公共部分中的 /etc/passwd 的符号链接。使用 --copy-unsafe-links 选项会导致在复制所有链接时,复制它们指向的目标文件。而使用 --safe-links 选项会导致接收方省略不安全的链接。注意,必须指定或隐含 --links 选项, --safe-links 才会生效。

如果符号链接的目标地址以根路径 (/) 开始、目标地址为空或者包含了足够多次访问上级目录的 ".." (多到可以访问 SRC 指定路径之外的路径),那么这个符号链接被认为 unsafe。在这些情况下,使用 --safe-links 选项会导致这些不安全的符号链接在接收端被省略。

以下是符号链接相关选项的解释总结。列表按优先顺序排列,所以如果您的选项组合没有被提及,请使用第一行是您选项的完整子集

以下是如何解释符号链接选项的摘要。该列表按优先顺序排列:

译者注: 作者只给了几个选项组合,然后介绍了几个选项,按理说这种摘要性质的章节应该放在选项解释章节之前,不知道为啥作者放后面了。

--copy-links

将所有符号链接解引用成普通文件和目录并传输 (在传输中不会有任何的符号链接)。

--copy-dirlinks

只将指向目录的符号链接解引用成目录并传输,其他符号链接的处理方式见下文。

--links --copy-ujsafe-links

将所有 unsafe 的符号链接解引用并传输,在接收端创建所有 safe 的符号链接。

--copy-unsafe-links

对所有 unsafe 的符号链接解引用并传输,所有 safe 的符号链接被忽略 (输出提示)。

--links --safe-links

接收端跳过创建 unsafe 的符号链接,只创建 safe 的符号链接。

--links

创建所有的符号链接。

有关符号链接选项 --munge-links 的解释,详细内容请查看该选项的相关部分。

需要注意的是, --keep-dirlinks 选项不影响符号链接在传输过程中的处理方式。它主要决定了 rsync 如何处理接收方已存在的目录符号链接。详见 --keep-dirlinks 选项。

23. 诊断

rsync 偶尔会产生一些看起来有点晦涩的错误消息。其中最容易引起困惑的是 "protocol version mismatch -- is your shell clean?" 错误。

这个错误通常是由于启动脚本或 remote shell 在 rsync 用于传输的流上产生了不必要的垃圾信息所致。诊断此问题的方法是以以下方式运行 remote shell:

ssh remotehost /bin/true > out.dat

然后查看 out.dat。如果一切正常,out.dat 应该是一个长度为 0 的文件。如果从 rsync 中收到上述错误,那么可能会发现 out.dat 包含一些文本或数据。查看内容并尝试找出是什么产生了它。最常见的原因是配置不正确的 shell 启动脚本 (例如 .cshrc 或 .profile),其中包含非交互式登录的输出语句。

如果在调试过滤规则时遇到困难,请尝试指定 -vv 选项。在这个详细程度上,rsync 会显示每个文件被包含或排除的原因。这有助于更好地理解哪些文件被同步或排除。

24. 返回值

  • 0 成功
  • 1 语法或使用错误
  • 2 protocol 不兼容
  • 3 错误地选择了输入/输出文件、目录
  • 4
    • 在一个不支持 64 位文件的平台上尝试操作 64 位文件
    • 客户端使用了一个服务器不支持的选项
  • 5 无法启动 client 与 server 连接的 protocol
  • 6 rsync daemon 无法向日志文件的末尾添加数据
  • 10 socket I/O 错误
  • 11 文件 I/O 错误
  • 12 rsync protocol 的数据流错误
  • 13 运行程序诊断出现错误
  • 14 IPC 代码错误
  • 20 收到了 SIGUSR1 或 SIGINT 信号
  • 21 收到了 waitpid() 返回的错误
  • 22 再给核心的内存缓冲分配内存时发生错误
  • 23 由于错误文件之传输了一部分
  • 24 由于传输列表中的文件消失了,导致传输只完成了一部分 (就是消失的文件没有被传输)
  • 25 --max-delete 选项让 rsync 不再删除文件了
  • 30 传输/接收数据时超时
  • 35 等待 rsync daemon 的连接超时

25. 环境变量

CVSIGNORE

该环境变量补充了 .cvsignore 文件中的忽略模式。详见 --cvs-exclude 选项。

RSYNC_ICONV

该环境变量设置了默认的 --iconv 设置。于 v3.0.0 首次引入

RSYNC_OLD_ARGS

环境变量值为 1 表示默认启用 --old-args 选项;值为 2 或更大,表示重复 --old-args 变量多次;值为 0 表示禁用 --old-args 选项。当设置了这个环境变量为非零值时,它将覆盖 RSYNC_PROTECT_ARGS 环境变量。

如果 rsync 命令中使用了 --old-args, --no-old-argssecluded-args 则该环境变量的值不起作用。

于 v3.2.4 首次引入。

RSYNC_REPORT_ARGS

如果用户希望默认启用 --secluded-args 选项,环境变量的值取非 0 值;如果用户希望默认禁用它,环境变量的值取 0。

如果 rsync 命令中指定了 --secluded-args, --no-secluded-args--old-args ,那么该环境变量会被忽略。

于 v3.1.0 首次引入。自 v3.2.4 开始,如果环境变量 RSYNC_OLD_ARGS 的值为非零值,该环境变量会被忽略。

RSYNC_RSH

该环境变量允许用户覆盖 rsync 使用的默认传输 shell。命令行选项可以在命令名后面添加,就像在 --rsh (-e)选项中一样。

RSYNC_PROXY

该环境变量允许用户将 rsync 客户端重定向,以使用 Web 代理连接到 rsync daemon。变量的值为 <host>:<port> 格式的字符串。

RSYNC_PASSWORD

该环境变量允许用户为 rsync 守护程序连接设置密码,从而避免密码提示。注意,环境变量指定的密码不能用于 remote shell (如 ssh)。

USER 或 LOGNAME

用户可以使用 USER 或 LOGNAME 环境变量来指定发送给 rsync daemon 的默认用户名。如果两者都没有设置,用户名默认为 "nobody"。如果两者都设置了,USER 优先级更高。

RSYNC_PARTIAL_DIR

该环境变量指定了用于 --partial 传输的目录,但不会隐含启用部分传输的 --partial 选项。详见 --partial-dir 选项。

RSYNC_COMPRESS_LIST

该环境变量允许用户指定一个压缩算法的名称列表来自定义压缩算法的协商。命令 rsync --version 可以查看可用的压缩算法的名称。详见 --compress 选项。

RSYNC_MAX_ALLOC

详见 --max-alloc 选项。

RSYNC_PORT

该环境变量不会被 rsync 读取,而是在 rsync 通过 remote shell 连接到 rsync daemon 时,在 remote shell 中设置该变量,以指定被 remote shell 拉起来的 rsync daemon 使用的端口号。这允许类似于 rsync-ssl 的脚本知道用户在命令行中指定的端口号。

HOME

该环境变量的值被用于查找用户的默认 .cvsignore 文件

RSYNC_CONNECT_PROG

该环境变量主要用于调试,它的值设置了连接到 rsync daemon 时设置要使用的程序。详见 连接到 rsync daemon 一节。

RSYNC_SHELL

该环境变量主要用于调试,它的值设置了连接到 rsync daemon 时设置要使用的程序。详见 连接到 rsync daemon 一节。

26. 文件

/etc/rsyncd.conf 或者 rsyncd.conf

27. 另见

rsync-ssl(1), rsyncd.conf(5), rrsync(1)

28. 已知问题

  • rsync 之间的时间传输使用 *nix 的 time_t 值
  • 向 FAT 文件系统传输数据时,rsync 可能会重新同步未修改的文件。见 --modify-window 选项的注释
  • 文件、设备等的权限使用本机的数值传输
  • --delete 选项的描述

如果用户发现 bug 请告诉我们!见网页 https://rsync.samba.org/

29. 版本

该 manpage 文档是 rsync v3.2.7 的文档。

30. 内部选项

选项 --server--sender 是 rsync 内部使用的,通常情况下不应由用户直接输入。某些情况下,可能需要了解这些选项,比如在设置仅能运行 rsync 命令的登录时。例如,rsync 发行版的支持目录中有一个名为 rrsync (受限制的 rsync) 的示例脚本,可与受限制的 ssh 登录一起使用。这些选项通常用于特定场景,不需要用户手动输入。

31. 信誉

rsync 使用 GNU 通用公共许可证进行分发。有关详情,请参阅 COPYING 文件。

rsync 网站位于 https://rsync.samba.org/ 。该网站包含 FAQ-O-Matic,可能会回答本手册未解答的问题。

rsync 的 GitHub项目网址为 https://github.com/WayneD/rsync

如果您喜欢这个程序,我们将非常高兴收到您的来信。请通过 [email protected] 联系邮件列表。

该程序使用了由 Jean-loup Gailly 和 Mark Adler 编写的优秀的 zlib 压缩库。

32. 感谢

特别感谢以下人士: John Van Essen, Matt McCutchen, Wesley W. Terpstra, David Dykstra, Jos Backus, Sebastian Krahmer, Martin Pool,以及已经离去但永远不会被遗忘的同伴 J.W. Schultz。

还要感谢 Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell 和 David Bell。如果我遗漏了一些人,请原谅。

33. 作者

rsync 最初由 Andrew Tridgell 和 Paul Mackerras 编写。之后许多人为其作出了贡献。目前由 Wayne Davison 进行维护。

支持和开发的邮件列表可在 https://lists.samba.org/ 上找到。



Last Update: 2023-10-06 Fri 09:31

Generated by: Emacs 28.2 (Org mode 9.5.5)   Contact: [email protected]

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议