linux上的rsync命令详解

1. rsync 简介

rsync 就是远程同步的意思remote sync.
rsync 被用在UNIX / Linux执行备份操作操作.
rsync 工具包被用来从一个位置到另一个位置高效地同步文件和文件夹. rsync可以实现在同一台机器的不同文件直接备份,也可以跨服务器备份.

2. rsync的重要特性

  • 速度快: 初次同步时, rsync会全量拷贝从源文件或目录到目标位置. 第二次往后同步时, rsync 仅仅会拷贝变化的数据块或字节到目标位置这将使得文件传输非常迅速.
  • 安全: rsync 可以使用ssh协议加密传输.
  • 占用带宽少: rsync 在发送时会压缩数据块, 接收后再解压缩数据块. 所以和其他文件传输协议比起来, rsync在跨主机传输文件时会占用较小的带宽.
  • 不需要特殊权限: 安装和运行rsync 不需要特殊权限.

3. 用法

rsync 语法如下

1
2
3
4
5
6
7
$  rsync [OPTION]... SRC [SRC]... DEST
or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
or rsync [OPTION]... [USER@]HOST:SRC [DEST]
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]

从语法结构我们可以看出, 源和目标即可以在本地也可以在远端. 如果是远端的话,需要指明登录用户名, 远端服务器名, 和远端文件或目录. 同时源可以是多个, 目标位置只能是一个.

4. 示例

4.1. 示例 1. 同步同一台机上的两个目录

1
2
3
4
5
6
7
8
$ rsync -zvr /var/opt/installation/inventory/ /root/temp
building file list ... done
sva.xml
svB.xml
.
sent 26385 bytes received 1098 bytes 54966.00 bytes/sec
total size is 44867 speedup is 1.63
$

说明:

-z: –compress 使用压缩机制

-v: –verbose 打印详细信息

-r: –recursive 以递归模式同步子目录

注意: 同步完成后, 我们会发现文件的时间戳timestamps发生了改变.

1
2
3
$ ls -l /var/opt/installation/inventory/sva.xml /root/temp/sva.xml
-r--r--r-- 1 bin bin 949 Jun 18 2009 /var/opt/installation/inventory/sva.xml
-r--r--r-- 1 root bin 949 Sep 2 2009 /root/temp/sva.xml

4.2. 示例 2: 保留文件的时间戳

有时我们希望拷贝或同步时, 时间戳不要发生变化, 源文件是什么时间戳,目标文件就是什么时间戳, 这时我们需要使用 -a –archive 归档模式选项. -a 选项相当于7个选项的组合 -rlptgoD

-r, –recursive: 递归模式Recursive mode
-l, –links: 将符号链接当作符号链接文件拷贝, 不拷贝符合链接指向的文件内容.
-p, –perms: 保留文件权限
-t, –times: 保留修改时间戳
-g, –group: 保留用户组信息
-o, –owner: 保留用户信息(需要超级用户权限)
-D, 相当于 –devices –specials 的组合, 保留设备文件, 保留特殊文件.

1
2
3
4
5
6
7
8
9
$ rsync -azv /var/opt/installation/inventory/ /root/temp/
building file list ... done
./
sva.xml
svB.xml
.
sent 26499 bytes received 1104 bytes 55206.00 bytes/sec
total size is 44867 speedup is 1.63
$

同步完成后, 我们再来看文件属性, 时间戳信息得到了保留, 不仅如此文件的所有者 和所在组也得到保留.

1
2
3
$ ls -l /var/opt/installation/inventory/sva.xml /root/temp/sva.xml
-r--r--r-- 1 root bin 949 Jun 18 2009 /var/opt/installation/inventory/sva.xml
-r--r--r-- 1 root bin 949 Jun 18 2009 /root/temp/sva.xml

4.3. 示例 3: 拷贝单个文件

1
2
3
4
5
$ rsync -v /var/lib/rpm/Pubkeys /root/temp/
Pubkeys

sent 42 bytes received 12380 bytes 3549.14 bytes/sec
total size is 12288 speedup is 0.99

说明: Pubkeys 是一个普通文件, /root/temp/是一个目录
-v: –verbose 打印详细信息

4.4. 示例 4. 从本地拷贝多个文件到远端

使用rsync, 也可以从本地拷贝多个文件或目录到远端, 以下即为示例:

1
2
3
4
5
6
7
8
9
10
$ rsync -avz /root/temp/ thegeekstuff@192.168.200.10:/home/thegeekstuff/temp/
Password:
building file list ... done
./
rpm/
rpm/Basenames
rpm/Conflictname

sent 15810261 bytes received 412 bytes 2432411.23 bytes/sec
total size is 45305958 speedup is 2.87

说明:

-z: –compress 使用压缩机制

-v: –verbose 打印详细信息

-a: -a –archive 归档模式选项, 详见示例2

注意:

与本地文件拷贝不同的地方在于, 当拷贝文件到远程服务器时, 我们指定远程主机上的用户名, 服务器地址, 路径等信息, 类似于使用scp命令拷贝,
与scp不同的地方在于, rsync更加强大, 支持各种选项, 最重要的一点是它支持断点续传.

如果没有设置ssh免密码登录我们还需要提供远程用户的密码等信息.有时你不想频繁输入密码, 或者rsync运行在一个无人执守的脚本里面, 这是需要预先设置ssh免密登录, 或者使用结合expect命令,自动输入密码, 但是出于安全考虑, 密码需要加密. 所以在条件许可的情况下, 还是推荐设置ssh免密登录.

4.5. 示例 5. 从远程服务器拷贝文件到本地

与示例 4 稍有不同, 这时远端目录或文件作为源位置, 本地目录或文件作为目标位置, 示例如下:

1
2
3
4
5
6
7
8
$ rsync -avz thegeekstuff@192.168.200.10:/var/lib/rpm /root/temp
Password:
receiving file list ... done
rpm/
rpm/Basenames
.
sent 406 bytes received 15810230 bytes 2432405.54 bytes/sec
total size is 45305958 speedup is 2.87

4.6. 示例 6. Remote shell for Synchronization

rsync 允许指定远程主机上运行shell命令.
这时需要使用 -e 选项:
-e, –rsh=COMMAND 指定远端使用的shell命令

Use rsync -e ssh to specify which remote shell to use. In this case, rsync will use ssh.

1
2
3
4
5
6
7
8
$ rsync -avz -e ssh thegeekstuff@192.168.200.10:/var/lib/rpm /root/temp
Password:
receiving file list ... done
rpm/
rpm/Basenames

sent 406 bytes received 15810230 bytes 2432405.54 bytes/sec
total size is 45305958 speedup is 2.87

4.7. 示例 7. 拷贝时不覆盖目标位置已修改过的文件

在一下特殊的使用场景中, 我们不希望拷贝文件时, 我们不希望拷贝过程覆盖掉目标位置中用户做出的修改. 这时我们需要使用 -u 选项明确的告诉rsync命令保留用户在目标文件中作出的修改. 在下面的例子中, 文件Basenames是用户基于上次的拷贝, 修改过的文件, 当我们使用了-u 选项后, 该文件中的修改将不会被覆盖掉.

1
2
3
$ ls -l /root/temp/Basenames
total 39088
-rwxr-xr-x 1 root root 4096 Sep 2 11:35 Basenames
1
2
3
4
5
6
7
$ rsync -avzu thegeekstuff@192.168.200.10:/var/lib/rpm /root/temp
Password:
receiving file list ... done
rpm/

sent 122 bytes received 505 bytes 114.00 bytes/sec
total size is 45305958 speedup is 72258.31
1
2
3
$ ls -lrt
total 39088
-rwxr-xr-x 1 root root 4096 Sep 2 11:35 Basenames

4.8. 示例 8. 仅拷贝目录结构, 不拷贝文件

在某些特殊场景中, 我们只需要远程服务器上的目录结构, 而不希望花大量时间, 带宽拷贝文件内容, 这时我们可以使用 -d, –dirs选项来达到目的.

1
2
3
4
5
6
7
8
9
10
$ rsync -v -d thegeekstuff@192.168.200.10:/var/lib/ .
Password:
receiving file list ... done
logrotate.status
CAM/
YaST2/
acpi/

sent 240 bytes received 1830 bytes 318.46 bytes/sec
total size is 956 speedup is 0.46

4.9. 示例 9. 文件传输时显示进度

有时我们希望拷贝文件时, 能实时的显示拷贝进度, 以及传输速率等信息. 尤其是拷贝大文件时, 程序不输出信息, 用户往往无法区分程序是在响应中, 还是已经挂起, 在这种情况下如果使用 –progress 就会非常有帮助.
rsync –progress option displays detailed progress of rsync execution as shown below.

1
2
3
4
5
6
7
8
9
10
11
12
$ rsync -avz --progress thegeekstuff@192.168.200.10:/var/lib/rpm/ /root/temp/
Password:
receiving file list ...
19 files to consider
./
Basenames
5357568 100% 14.98MB/s 0:00:00 (xfer#1, to-check=17/19)
Conflictname
12288 100% 35.09kB/s 0:00:00 (xfer#2, to-check=16/19)

sent 406 bytes received 15810211 bytes 2108082.27 bytes/sec
total size is 45305958 speedup is 2.87

你也可以使用rsnapshot工具 (rsnapshot会调用rsync)来备份本地linux服务器, 或者备份远程linux服务器.

4.10. 示例 10. 同步时删除目标位置多余的文件或目录

有时我们希望目标文件和源文件保持严格地一致, 不要多文件也不要少文件, 这是我们可能需要使用 -delete 选项来达到目的. 如果使用 -delete 选项, rsync将删除目标位置多余的文件或文件夹. 此选项还可以结合–delete-excluded 选项一起使用, 添加一些例外的文件.

1
2
# 现在Source and target 文件是一致的. 现在让我们在目标位置创建一个新文件.
$ touch new-file.txt
1
2
3
4
5
6
7
8
$ rsync -avz --delete thegeekstuff@192.168.200.10:/var/lib/rpm/ .
Password:
receiving file list ... done
deleting new-file.txt
./

sent 26 bytes received 390 bytes 48.94 bytes/sec
total size is 45305958 speedup is 108908.55

上述示例中, new-file.txt 是源文件中没有的文件, 其将会在拷贝时被删除掉.

4.11. 示例 11. Do not Create New File at the Target

在某些特殊的场景下, 我们只想更新, 目标位置已经存在的文件或目录, 而不关心源位置的新文件, 这时我们可以使用-existing 选项仅仅更新已经存在的文件.
让我们来验证一下这个选项的功能, 首先在源端添加一个新文件 new-file.txt.

1
2
[/var/lib/rpm ]$ > new-file.txt
Next, execute the rsync from the target.
1
2
3
4
5
6
$ rsync -avz --existing root@192.168.1.2:/var/lib/rpm/ .
root@192.168.1.2s password:
receiving file list.. done

sent 26 bytes received 419 bytes 46.84 bytes/sec
total size is 88551424 speedup is 198991.96

从上面的例子可以看到, 由于加了–existing选项新文件new-file.txt没有被拷贝到目标位置

4.12. 示例 12. 查看目标位置和源位置之间的差异

选项-i, –itemize-changes 非常有用, 当我们想了解目标位置和源位置的文件差异时. 此选项可以用在拷贝前或拷贝后比较差异.

在源端:

1
2
3
4
$ ls -l /var/lib/rpm
-rw-r--r-- 1 root root 5357568 2010-06-24 08:57 Basenames
-rw-r--r-- 1 root root 12288 2008-05-28 22:03 Conflictname
-rw-r--r-- 1 root root 1179648 2010-06-24 08:57 Dirnames

在目标端:

1
2
3
4
$ ls -l /root/temp
-rw-r--r-- 1 root root 12288 May 28 2008 Conflictname
-rw-r--r-- 1 bin bin 1179648 Jun 24 05:27 Dirnames
-rw-r--r-- 1 root root 0 Sep 3 06:39 Basenames

注意: 在上面的例子中, 源位置和目标位置有两处差异. 第一, 源文件Basenames的所有者和组与目标文件不同, 第一Dirnames文件大小也不一样.
现在让我们来看看rsync会怎样显示这些差异

1
2
3
4
5
6
7
8
$ rsync -avzi thegeekstuff@192.168.200.10:/var/lib/rpm/ /root/temp/
Password:
receiving file list ... done
>f.st.... Basenames
.f....og. Dirnames

sent 48 bytes received 2182544 bytes 291012.27 bytes/sec
total size is 45305958 speedup is 20.76

输出信息只在相应文件前面显示了9个字母来标识改变, 这些字母具体是什么意思呢? 请参考以下详细说明

表示文件已经被拷贝到了本地
f 代表该项目是一个文件.
s 代表文件大小发生了变化.
t 代表时间戳有差异.
o 所有者有差异
g 所属组有差异.

4.13. 示例 13. 使用通配符过滤文件

rsync 可以使用–include 和 –exclude 选项结合通配符进行文件或文件夹过滤

1
2
3
4
5
6
7
8
9
10
11
$ rsync -avz --include 'P*' --exclude '*' thegeekstuff@192.168.200.10:/var/lib/rpm/ /root/temp/
Password:
receiving file list ... done
./
Packages
Providename
Provideversion
Pubkeys

sent 129 bytes received 10286798 bytes 2285983.78 bytes/sec
total size is 32768000 speedup is 3.19

在上面的示例中, 仅仅以P打头的文件和文件夹被包含了进来, 其他的文件都被过滤掉, 在拷贝的过程中被排除在外了.

4.14. 示例 14. 不拷贝大文件

可以使用–max-size 告诉rsync 不要拷贝大小超过某个值的文件, 可以使用K, M, G指定文件大小, M for megabytes and G for gigabytes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ rsync -avz --max-size='100K' thegeekstuff@192.168.200.10:/var/lib/rpm/ /root/temp/
Password:
receiving file list ... done
./
Conflictname
Group
Installtid
Name
Sha1header
Sigmd5
Triggername

sent 252 bytes received 123081 bytes 18974.31 bytes/sec
total size is 45305958 speedup is 367.35

4.15. 示例 15. 拷贝整个文件

rsync 有个重要优点就是, 可以做到在拷贝的过程中, 只拷贝发生变化了的部分, 而不是发送整个文件.
但是在某些场景中, 比如文件较少, 文件size较小时, 我们的带宽又足够大, cpu资源相对又贫乏, 我们不希望它这样做, 因为毕竟计算源端和目标端的checksum, 并做对比, 也需要额外cpu开销. 这时我们可以使用 -W, –whole-file 选项, 让rsync不用计算那么多, 一上来就直接开始传送文件. 我们可以像下面这么做.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#  rsync -avzW  thegeekstuff@192.168.200.10:/var/lib/rpm/ /root/temp
Password:
receiving file list ... done
./
Basenames
Conflictname
Dirnames
Filemd5s
Group
Installtid
Name

sent 406 bytes received 15810211 bytes 2874657.64 bytes/sec
total size is 45305958 speedup is 2.87

4.16. 示例 16. 断点续传

默认的情况下,当rsync传输中断后,新的rsync传输将删除所有的未完成的残余文件片段,然后开始新的传输。
而使用–partial后,将会进行我们所说的断点续传。
值得注意的是-P这个参数是综合了–partial –progress两个参数,所以rsync的断点续传可以用下面的例子来说明:

1
rsync -avzP /tmp/bigfile cnangel@10.1.6.160:/tmp/bigfile

5. 相关文章

本文原文位于鹏叔的技术博客 - linux上的rsync命令详解, 获取最近更新请访问原文.

更多linux相关知识, 请参考鹏叔的技术博客linux tag, 获取实时更新的Linux文章.

6. 参考文档

15个Rsync命令实例