rsync以及与scp和cp的比较

记录下rsync的用法以及与scp和cp的比较。

rsync 是一个常用的 Linux 应用程序,用于文件同步。

它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cpmv命令。

与其他文件传输工具(如 FTP 或 scp)不同,rsync 的最大特点是会检查发送方和接收方已有的文件,仅传输有变动的部分(默认规则是文件大小或修改时间有变动)。

rsync 可以做的事情也远不止复制文件。它还有很多功能比如同步、差量传输、即时压缩等。

安装

sudo apt-get install rsync

复制文件和复制目录

那么从最常见的场景开始:复制文件和复制目录

复制文件

对于复制单个文件而言,scp 和 rsync 命令实际上是等价的。

比方说,你需要把 a.txt 传到你在名为 server 的服务器上的主目录下

scp a.txt me@server:/home/me/

相应的 rsync 命令只需要输入 rsync 取代 scp:

rsync a.txt me@server:/home/me/

复制目录

对于复制目录,就有了分歧。 如果你想把 dir_a 目录复制到 server 服务器上,除了指定 ssh 信息外,相应的 scp 和 cp 一模一样。

scp -r dir_a/ me@server:/home/me/

对于 rsync,考虑的因素会比较多。首先,我们来看一下最简单的形式:

rsync -r dir_a/ me@server:/home/me/

对于只包含目录和普通文件的简单情况,这就可以了。

区别

然而,对于其他文件则产生了区别。rsync 更在意发送与主机系统中一模一样的文件。

mkdir -p dir_a/dir_b		#创建多级目录结构。参数说明 -p 确保目录名称存在,不存在的就建一个。
touch dir_a/a.txt			#在其根目录下创建文件
cd dir_a/dir_b
ln -s ../a.txt link.txt		#创建一个符号链接指回到该文件
cd ../
tree
.
├── dir_b
│   └── link.txt -> ../a.txt
└── a.txt
1 directory, 2 files

在scp工具使用上面的指令,然后ssh进入服务器查看 dir_a 的目录树,就会发现出现了区别:

.
├── dir_b
│   └── link.txt
└── a.txt
1 directory, 2 files

link.txt 不再是一个符号链接,它现在是一个 a.txt 的完整副本。

如果你尝试使用 cp -r 复制 dir_a 目录,你会得到一个新的目录,里面的符号链接和 dir_a 的一样。

现在换用 rsync 命令,则会得到一个警告:

rsync -r dir_a/ me@server:/home/me/
skipping non-regular file "dir_a/dir_b/link.txt"

rsync 警告我们它发现了一个非常规文件,并正在跳过它。

添加 -links 标志。使得rsync可以复制符号链接。

rsync -r --links dir_a/ me@server:/home/me/

在远程服务器上,我们看到这个符号链接是作为一个符号链接复制过来的。这与 scp 复制符号链接的方式不同。

.
├── dir_b
│   └── link.txt -> ../a.txt
└── a.txt
1 directory, 2 files

-a 参数

-a参数可以替代-r,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等)。

由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新,所以-a-r更有用。下面的用法才是常见的写法。

rsync -av source destination

-v参数是将结果输出到终端,这样就可以看到哪些内容会被同步。

source目录表示源目录,destination表示目标目录。目标目录如果不存在,rsync 会自动创建。

执行上面的命令后,源目录source被完整地复制到了目标目录destination下面,即形成了destination/source的目录结构。

如果只想同步源目录source里面的内容到目标目录destination,则需要在源目录后面加上斜杠。

rsync -av source/ destination

注意,rsync 会同步以”点”开头的隐藏文件,如果要排除隐藏文件,可以加上--exclude=".*"

连接自定义ssh端口

scp -P 8022 a.txt me@server:/home/me/

而 rsync 则为

rsync -e 'ssh -p 8022' a.txt me@server:/home/me/

rsync 也会使用你的 ssh 配置。在 ~/.ssh/config定义 Port 就不需要再为 rsync 或 scp 命令指定端口了。

rsync:// 协议

rsync://协议默认端口为873

rsync -av source/ 192.168.122.32::module/destination

上面地址中的module并不是实际路径名,而是 rsync 守护程序指定的一个资源名,由管理员分配。

如果想知道 rsync 守护程序分配的所有 module 列表,可以执行下面命令。

rsync rsync://192.168.122.32

rsync 协议除了使用双冒号,也可以直接用rsync://协议指定地址。

rsync -av source/ rsync://192.168.122.32/module/destination

总结

对于简单的使用情况,rsync 并不比老牌的 scp 工具难用多少。唯一显著的区别是在递归复制目录时使用 -a 而不是 -r

rsync 的 -a 比 scp 的 -r 更像 cp 的 -r

参考链接

rsync 用法教程 - 阮一峰

该从scp转向rsync了