rsync - a fast, versatile, remote (and local) file-copying tool

广泛用于备份(backup)镜像(mirror)

支持本地或远程复制, 有shellrsync daemon两种方式

使用方式

Local:
    rsync [OPTION...] SRC... [DEST]

Access via remote shell:
    Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

Access via rsync daemon:
    Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
          rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
          rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

Usages with just one SRC arg and no DEST arg will list the source files instead of copying.

本地同步

rsync [OPTION...] SRC... [DEST]

remote shell方式 远程同步

使用一个冒号:分隔主机和目录

Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

可以使用sshrsh方式传输

举例:

# 使用ssh方式, 端口为1234. 传输主机tankywoo的/data目录到本地的/tmp/backup下
rsync -e 'ssh -p 1234' root@tankywoo:/data /tmp/backup/

rsync daemon方式 远程同步

有两种方式:

常用参数

列出可用modules(只有module未配置list = no的才会被列出):

rsync 192.168.1.100::

查看文件列表:

rsync --list-only bob@192.168.1.100::mymodule

常用的mirror同步命令:

rsync -hvaHEXA --delete --stats --progress --numeric-ids --exclude-from=/root/filter_file tankywoo::wiki /data

rsyncd 可以配置多个modules, 如:

[mymodule]
    uid = root
    gid = root
    path = /home/test/
    numeric ids = yes
    list = no
    exclude from = /path/to/file
    ignore errors
    auth users = bob
    secrets file = /etc/rsyncd.secrets
    hosts allow = 192.168.1.101
    comment = "for rsyncd test"

经验

关于 hosts allow 和 hosts deny

如果只设置了hosts allow, 则不符合的都会拒绝连接(reject).

如果同时设置了hosts allowhosts deny, 则首先会判断是否符合allow列表, 如果符合则连接, 否则判断deny连接, 如果符合则拒绝, 剩下的都允许连接.

另外, 这两个配置项都可以是全局级的.

逻辑上有点绕, 所以感觉这个如果没有仔细看文档和尝试的话, 容易造成安全问题.

这里也可以使用通配符(wildcards) *.

关于认证用户和密码

auth userssecrets file 控制.

前者列出允许连接module的用户, 后者管理用户和密码.

普通的设置只是简单的帐号密码匹配, 这套用户密码体系和本地用户(/etc/passwd)是无关的.

也可以配置groupname matching, 组名使用@前缀, 此时认证用户必须是本地系统上存在的真实用户, 且是这个组下的成员.

关于 filter, exclude, exclude from 等

排除的文件路径, 始终是相对路径, 相对于path的路径.

exclude 配置排除的模式

exclude from 配置排除文件, 包含多行排除模式/文件, 一个module只能配置一个此配置项, 配置多个的话以最后一个为主. 但是客户端命令可以指定多个--exclude-from, 且都生效.

Only one "exclude from" parameter can apply to a given module; if you have multiple exclude-from files, you can specify them as a merge file in the "filter" parameter.

排除模式可以使用-+来显示的指定excludeinclude.

关于filter和exclude from的区别:

这里还有些疑惑的地方:

如果配置了use chroot = yes, 那么感觉exclude from 以及 filter 指定的文件都应该是相对路径, 相对于path, 但是实际还是要配置绝对路径, 否则报错.

不过, filter是可以显式配置为相对:

filter = : .rsync-filter

这样就是相对了path配置的路径下的.rsync-filter文件.

另外就是关于:

you can specify them as a merge file in the "filter" parameter

这里不清楚怎么使用? TODO

关于权限问题

同步时会看到有些文件报 failed: Permission denied, uid 选项给出了说明:

The default when run by a super-user is to switch to the system’s "nobody" user. The default for a non-super-user is to not try to change the user.

所以需要配置 uid = root (或其它足够的权限)

rsync命令行只同步所有子目录指定的文件

例子:

dir
|---sub_dir1
|   |-file_a
|   |-file_b
|   |-file_c
|---sub_dir2
|   |-file_a
|   |-file_b
|   |-file_c
|---sub_dir3
|   |-file_a
|   |-file_b
|   |-file_c
|...

即某个目录下一堆子目录,每个子目录下都有一堆同名文件,现在只想同步各子目录下的 file_b:

$ rsync -hvarHEXAi --stats --progress --filter="+ *file_b" --filter="+ */" --filter="- *" root@server:/dir/ /dir/

如果是rsync server端,配合 filter 还是比较好弄,记得以前做过。

注意上面 --filter="+ */" --filter="- *" 是个 trick。后者排除所有,前者不排除所有子目录。具体是看了文档PATTERN的描述:

Note that, when using the --recursive (-r) option (which is implied by -a), every subcomponent of every path is visited from the top down, so include/exclude patterns get applied recursively to each subcomponents full name (e.g. to include "/foo/bar/baz" the subcomponents "/foo" and "/foo/bar" must not be excluded). The exclude patterns actually short-circuit the directory traversal stage when rsync finds the files to send. If a pattern excludes a particular parent directory, it can render a deeper include pattern ineffectual because rsync did not descend through that excluded section of the hierarchy. This is particularly important when using a trailing * rule. For instance, this wont work:

    + /some/path/this-file-will-not-be-found
    + /file-is-included
    - *

This fails because the parent directory "some" is excluded by the * rule, so rsync never visits any of the files in the "some" or "some/path" directories. One solution is to ask for all directories in the hierarchy to be included by using a single rule: "+ */" (put it somewhere before the "- *" rule), and perhaps use the --prune-empty-dirs option. Another solution is to add specific include rules for all the parent dirs that need to be visited. For instance, this set of rules works fine:

    + /some/
    + /some/path/
    + /some/path/this-file-is-found
    + /file-also-included
    - *

Troubleshoot

rsync: didn't get server startup line

测试时配置的exclude from是一个无效路径, 导致这个错误

auth failed on module xxx

rsync auth failed on module xxx 问题总结