Rsync 命令

 

使用 rsync 作为数据同步及备份工具。

RSYNC 命令常用选项

-r 选项

-r--recursive 表示递归同步子目录,如果要同步目录,必须要加上此选项。

-a 选项

-a--archive 代表 archive mode,相当于同时应用 -rlptgoD 这些选项,表示递归并保留大部分原文件属性。

  • -r, --recursive 递归
  • -l, --links 同步软链接
  • -p, --perms 保留读写权限
  • -t, --times 保留修改时间
  • -g, --group 保留属组
  • -o, --owner 保留属主
  • -D 表示 --devices--specials
    • --devices 同步设备文件
    • --specials 同步特殊文件,如 name sockets 和 fifos

-h 选项

-h--human-readable 以友好可读的方式输出数字,可读方式有四种级别:

  • level 0: 输出纯数字
  • level 1: 每三个数字用逗号或点号分隔
  • level 2: 以 1000 为单位输出数字 (较大单位的字符后辍见下面)
  • level 3: 以 1024 为单位输出数字

使用规则为:

  • 不使用 -h,那么同步时的默认级别为 level 1
  • 使用 -h,级别为 level 2
  • 使用 -hh,级别为 level 3
  • 使用 --no-human-readable (--no-h),级别降低为 level 0

level 2level 3 级别的单位字母后辍是:K(kilo), M(mega), G(giga), T(tera), P(peta)。例如,一个 1234567 字节的文件在 level 2 中输出为 1.23M。

向后兼容性: 3.1.0 之前的 rsync 版本不支持 level 1,且默认级别为 level 0。因此,使用 -h-hh 选项在新旧版本中都表示 level 2level 3

-P 选项

-P 表示 --partial--progress

  • --partial 默认情况下,如果传输中断,rsync 将删除那些部分传输的文件,使用 --partial 选项可以保留部分传输文件,再次同步文件时,这些部分传输文件不用重新开始,使得传输速度更快。
  • --progress 显示传输进度
    • 当文件正在传输时,显示

      782448      63%  110.64kB/s    0:00:04
      
      已传输字节 完成度 传输速率 剩余时间
      782448 63% 110.64kB/s 4秒
    • 当文件传输完成时,显示

      1,238,099 100%  146.38kB/s    0:00:08  (xfr#5, to-chk=169/396)
      
      文件大小 完成度 传输速率 用时 xfr#5, to-chk=169/369
      1,238,099 100% 146.38kB/s 8秒 传输的第5个普通文件,总共369个文件,还剩169个文件待检查是否最新

-z 选项

-z--compress 会压缩文件后再进行传输。rsync 支持多种压缩格式,运行 rsync --version 查看编译到当前版本中的默认压缩格式列表。

当传输双方的版本都是 3.2.0 以上时,rsync 会从客户端的压缩格式列表中选择第一个同时在客户端与服务器中存在的压缩格式。如果没有相同的压缩格式,rsync 将退出并显示错误。如果服务器端 rsync 太旧而不支持压缩格式协商,则假定其列表为“zlib”

有一些较旧的 rsync 版本会因为它们的压缩库不兼容默认的 zlib 压缩格式而拒绝 -z 选项并要求使用 -zz 选项,通常可以忽略这种奇怪的情况,除非 rsync 服务器要求必须指定 -zz 选项。

–list-only 选项

列出而不是传输源目录,类似于使用 ls 命令列出源目录。此时,如果是单个源目录可以不给出目标目录,如果是多个源目录,则必须给出目标目录。

-n 选项

-n--dry-run 模拟实际的运行效果,但不真的执行同步,通常与 -v, --verbose-i, --itemize-changes 一起使用。

-v 选项

-v--verbose 增加在传输过程中显示的信息。默认情况下,rsync 是静默工作。-v 提供正在传输文件的信息以及传输完成后的简短摘要。-vv 还提供跳过了哪些文件,并在传输完成后提供更多信息。只有在调试 rsync 时才应使用两个以上的 -v 选项。

-i 选项

-i--itemize-changes 列出源目录与目标目录中有差异的文件,并给出差异信息,具体差异信息的解释参考 rsync 手册页。

–delele 选项

使目标目录和源目录的内容保持完全一致,删除掉存在于目标目录而不在源目录中的文件。此选项必须是传输整个目录,即传输的是 "dir""dir/",如果传输的是 "dir/*",则 shell 会将其扩展成多个单独的文件。被 --exclude 排除的文件不会被删除。

–stats 选项

打印文件传输的统计信息,具体请参考 rsync 手册页。

RSYNC 的过滤规则

以下内容参考自rsync命令过滤规则入门教程

过滤规则的语法

操作 [匹配模式]

操作[,]修饰符 [匹配模式]

操作

序号 长标识 短标识 操作说明 说明
1 exclude - 排除操作 排除符合匹配模式的路径
2 include + 包含操作 包含符合匹配模式的路径
3 merge . 引入规则文件  
4 dir-merge : 指定每个目录里要合并的规则文件 针对传输目录,不常用
5 hide H 指定从传输中隐藏文件的模式  
6 show S 指定某些文件不会被隐藏  
7 protect P 指定某些文件受保护不被删除  
8 risk R 指定某些文件不受保护  
9 clear ! 清除当前包含/排除列表 无匹配模式

修饰符

  1. 修饰符 / 将文件路径从相对路径转换为绝对路径。
  2. 修饰符 ! 对匹配结果取反。

过滤规则选项

  • --include=PATTERN: 设定一条包含规则, 如: --include='*.php'
  • --exclude=PATTERN: 设定一条排除规则, 如: --exclude='*'
  • --include-from=FILE: 指定一个文件,文件中一行一条包含规则,以 ;# 开头的行为注释,空行被忽略
  • --exclude-from=FILE: 指定一个文件,文件中一行一条排除规则,以 ;# 开头的行为注释,空行被忽略
  • --filter=RULE, -f: 设定一条过滤规则,可以是包含规则或排除规则,如: -f '+ *.php', -f '- *', 也可以是一个规则文件,如: -f '. ./rsynce.rules'

--filter=RULE, -f 选项支持完整的规则表达语法,其它选项都可以转化为此选项的表达。如:

# --include='xxx' 等价于 -f '+ xxx'
# --exclude='xxx' 等价于 -f '- xxx'
rsync -av --include='*.php' --exclude='*' src_dir/ dst_dir/
rsync -av -f '+ *.php' -f '- *' src_dir/ dst_dir/

匹配模式

匹配模式用于匹配传输路径。匹配模式就是描述路径特征的一个字符串,如 *.php 描述的就是路径末尾的名称 (路径必须是 .php 结尾)。

传输路径

传输路径是指 src_dir/ 中目录或文件的相对路径,如果使用修饰符 /,则是绝对路径

server.php
services.php
session.php
view.php
config/
config/services.php
config/session.php
config/view.php
routes/
routes/api.php
routes/channels.php
routes/console.php
routes/web.php

10条匹配模式规则

  1. 模式以 / 开头时,表示模式必须匹配路径的开始;否则可以匹配路径中任意一层名称。如:/*.php
  2. 模式以 / 结尾时,表示模式只匹配目录,否则可以匹配目录或文件。如:config/, 而 config/***/ 则匹配 "config" 目录和其下的所有子目录。
  3. 模式中间的 / 表示路径分隔符。如:subdir/view.php
  4. * 匹配任意长度的任意字符,但不匹配 /。如:*.php
  5. ** 结尾时匹配任意长度的任意字符(包括 /)。如:app/** 匹配路径 "app/xx/xx/a.txt"
  6. *** 结尾时匹配任意长度的任意字符(包括 /),还包括目录本身。如:app/*** 匹配路径 "app""xxx/app"
  7. ? 匹配 / 以外的任意一个字符
  8. [] 匹配一个某一类字符,如:[a-z] 匹配一个小写字母,[0-9] 匹配一个数字
  9. 模式默认必须匹配到路径的末尾。如:foo 匹配 "foo""xx/foo",但不匹配 "xx/foo1""foo/xx"
  10. 路径被匹配的部分必须是包含完整的(目录或文件)名称,不可从名称中间切开。如:foo 不匹配 "xxx/afoo"abc/foo 不匹配 "subdir/aabc/foo"

Include/Exclude pattern rules

以下内容参考自 rsync 手册页。

规则名可以使用长名或短名,后跟空格,然后跟模式或文件名

长规则名 短规则名 作用
exclude - specifies an exclude pattern.
include + specifies an include pattern.

模式中可以包含以下通配符

通配符 作用
* 匹配任何 path component,遇到斜杠 / 停止
** 匹配任何内容,包括斜杠
? 匹配除斜杠 / 以外的任何字符
[ 引入字符类,例如 [a-z][[:alpha:]]

如果模式包含 / (不包括结尾的 /)或 **,则它将与完整路径名匹配(算法是递归应用的,因此 完整文件名 实际上可以是从起始目录向下的路径的任何部分)。如果模式不包含 /**,则仅与文件名的最后部分匹配。

child_dir/*** 将匹配 "child_dir" 目录本身和该目录的所有内容,包括所有子目录(等于同时应用 child_dir/child_dir/**)。child_dir/***/ 将匹配 "child_dir" 目录和其下所有子目录,但不包含任何文件,相当于只同步了目录结构。

下表是 include/exclude 的例子

规则 匹配结果
- *.o 排除所有与 *.o 匹配的名称
- /foo 在根目录中排除名为 foo 的文件或目录
- foo/ 排除任何名为 foo 的目录
- /foo/*/bar 排除任何位于根目录中名为 foo 的目录下两层的名为 bar 的文件
- /foo/**/bar 排除传输根目录中名为 foo 的目录下两层或两层以上的名为 bar 的文件
+ */, + *.c- * 包括所有目录和C源文件,但不包含其他内容
+ foo/, + foo/bar.c-* 仅包括 foo 目录和 foo/bar.c(必须明确包含 foo 目录,否则 * 将排除该目录)

include/exclude 的解释,具体请参考 man rsync 中的 FILTER RULES 一节。

当要传输的文件/目录列表建立后,rsync会依次检查要传输的每个文件名,根据 include/exclude 模式列表,应用最先匹配文件名的模式:如果先匹配到 exclude 模式,则不传输该文件;如果先匹配到 include 模式,则传输该文件;如果没有匹配的模式,则传输该文件。

另外,以斜杠结尾的内容是匹配目录(就像 find -type d)

RSYNC 使用举例

断点续传

rsync -avhPz src_dir dst_dir

显示整体拷贝速率

rsync --ah --partial --info=progress2 src_dir dst_dir

这里不能使用 -v-P 参数,否则还是会显示单个文件的传输速率。

测试同步结果

如果不确定 rsync 执行的结果,可以不写目标目录,这样不会同步数据,只会输出要同步的目录和文件列表。

rsync -avhP src_dir/

同步远程目录

将远程目录 sync@gitmaster:/repo/ 下的所有文件同步到本地 /repo 下,使用 --delete 删除目标目录中比源目录多出的文件,不同步源目录下的 rpms/baksrc/windows 目录,不同步 /sync/config/exclude-list.txt 文件中列出的文件或目录。

rsync -avhPz --stats --delete --exclude=rpms/bak --exclude=src/windows --exclude-from=/sync/config/exclude-list.txt sync@gitmaster:/repo/ /repo

注意: 源目录如果以 / 结尾,表示将源目录下的所有文件同步到目标目录下,不包含目录本身。如果源目录不是以 / 结尾,表示将源目录同步到目标目录下,包含目录本身

rsync 可以同时同步多个源目录到一个目标目录,但不能从一个源目录同步到多个目标目录。

通过跳板机同步文件 (-e)

rsync -avhPz -e 'ssh -ax -J USER@PROXYHOST' REMOTEHOST:foo/bar .
rsync -avhPz -e 'ssh -o "ProxyCommand ssh -ax USER@PROXYHOST -W %h:%p"' USER@REMOTEHOST:foo/bar .

递归列出文件但不同步 (-r, –list-only)

rsync -r --list-only src_dir/

比较源和目标 (-i)

rsync -avhzi src_dir/ dst_dir/

同步源目录及其所有子目录下的PHP文件 (–include=”PATTERN”, –exclude=”PATTERN”)

rsync -avhPz --prune-empty-dirs --include='*/' --include='*.php' --exclude='*' src_dir/

# 等价形式
rsync -avhPz -m -f '+ */' -f '+ *.php' -f '- *' src_dir/

上面命令按以下顺序过滤 src_dir/ 下的目录和文件列表

  1. 不包含空目录,
  2. 包含所有目录 (包括子目录)
  3. 包含所有匹配 *.php 的文件
  4. 不包含任何其它文件

rsync 默认包含所有未匹配到的文件,上面的规则4用来阻止默认规则,可以排除其它文件。

同步一级子目录

以下命令等价,只是思路不同。效果是:只同步 config 目录 (包括所有子目录和文件)

# 使用了模式规则1、4
# 因模式规则1,-f '- /*'规则排除了str_dir目录下出config外所有的文件和子目录
# 递归扫描config目录时,因不命中任何规则,所有子目录和文件都被默认包含
rsync -av -f '+ config' -f '- /*'  src_dir/

# 使用了模式规则4、5、9
# -f '+ config'匹配config目录并包含
# -f '+ config/**' 匹配config目录下所有的子目录和文件的路径,包含。模式规则5
# 其余所有的路径被 -f '- *'匹配,排除。模式规则4、9
rsync -av -f '+ config/**' -f '+ config' -f '- *'  src_dir/

# -f '+ config/***' 匹配config目录以及其所有子目录和文件。规则6
rsync -av -f '+ config/***'  -f '- *'  src_dir/

# 使用修饰符!取反,排除了config目录以及其所有子目录和文件路径以外的路径
# 相当于只同步config目录
rsync -av -f '-! config/***' src_dir/

同步一级子目录但排除PHP文件

以下命令等价,效果是:只同步 config 目录,但排除其中的 php 文件 (包括子目录)

rsync -av -f '+ config' -f '- /*' -f '- *.php' src_dir/

rsync -av -f '- *.php' -f '+ config/***' -f '- *' src_dir/

同步一级子目录下的PHP文件

效果是:只同步 config 目录下的 php 文件 (包括子目录)

rsync -av -f '+ config/***/' -f '+ *.php' -f '- *' src_dir/

快速复制目录结构

有时需要需要创建一个目录,其子目录层次结构与另一个目录结构一样,但不需要其中的文件,这可以用rsync命令快速完成

# 使用了修饰符!取反,排除了目录以外的路径。模式规则1
rsync -av -f '-! */' src_dir/ dst_dir/