在 Linux 系统下,数据备份的工具很多,除了前面介绍了 tar、cpio、dd 命令之外,本节再介绍一个用来备份数据的命令,就是 rsync。
从字面意思上,rsync 可以理解为 remote sync(远程同步),但它不仅可以远程同步数据(类似于 scp
命令),还可以本地同步数据(类似于 cp 命令)。不同于 cp 或 scp 的一点是,使用 rsync
命令备份数据时,不会直接覆盖以前的数据(如果数据已经存在),而是先判断已经存在的数据和新数据的差异,只有数据不同时才会把不相同的部分覆盖。
在系统学习 rsync 命令之前,请确认你的 Linux 系统中已经安装有此命令,如果没有,可以直接使用 yum install -y rsync 命令安装。
讲解 rsync 用法之前,为了让大家对此命令有一个整体的认识,这里先举个例子:
[root@localhost ~]# rsync -av /etc/passwd /tmp/1.txt
sending incremental file list
sent 34 bytes received 15 bytes 98.00 bytes/sec
total size is 1432 speedup is 29.22
此例中,通过执行 rsync 命令,实现了将 /etc/passwd 文件本地同步到 /tmp/ 目录下,并改名为 1.txt。
除此之外,rsync 命令还支持远程同步数据,也就是将本地的数据备份到远程机器上。比如说,我们知道远程机器的 IP 地址为 192.168.65.67,用户名为generic,则使用 rsync 命令备份kms.txt 文件的执行命令为:
[root@localhost ~]# rsync -av /home/kms.txt generic@192.168.65.67:/tmp/bak.txt
generic@192.168.188.128's password: <-- 输入密码
sending incremental file list
kms.txt
sent 31 bytes received 12 bytes 7.82 bytes/sec
total size is 1432 speedup is 54.91
注意:
首次远程连接时,会提示是否要继续连接,输入 yes 即可。另外,当成功建立连接后,需要输入目标系统的 root 密码。
传输的双方都必须安装 rsync。
通过以上 2 个实例,读者应该能对“rsync既支持本地备份数据,还支持远程备份数据”有了直观的认识。那么,rsync 命令要怎样使用呢?
rsync 命令的基本格式有多种,分别是:
[root@localhost ~]# rsync [OPTION] SRC DEST
[root@localhost ~]# rsync [OPTION] SRC [USER@]HOST:DEST
[root@localhost ~]# rsync [OPTION] [USER@]HOST:SRC DEST
[root@localhost ~]# rsync [OPTION] [USER@]HOST::SRC DEST
[root@localhost ~]# rsync [OPTION] SRC [USER@]HOST::DEST
针对以上 5 种命令格式,rsync 有 5 种不同的工作模式:
第一种用于仅在本地备份数据;
第二种用于将本地数据备份到远程机器上;
第三种用于将远程机器上的数据备份到本地机器上;
第四种和第三种是相对的,同样第五种和第二种是相对的,它们各自之间的区别在于登陆认证时使用的验证方式不同。
要知道,使用 rsync 在远程传输数据(备份数据)前,是需要进行登陆认证的,这个过程需要借助 ssh 协议或者 rsync 协议才能完成。在
rsync 命令中,如果使用单个冒号(:),则默认使用 ssh 协议;反之,如果使用两个冒号(::),则使用 rsync 协议。
ssh 协议和 rsync 协议的区别在于,rsync 协议在使用时需要额外配置,增加了工作量,但优势是更加安全;反之,ssh 协议使用方便,无需进行配置,但有泄漏服务器密码的风险。
另外,以上几种格式中各个参数的含义如下:
- SRC:用来表示要备份的目标数据所在的位置(路径);
- DEST:用于表示将数据备份到什么位置;
- USER@:当做远程同步操作时,需指明系统登录的用户名,如果不显示指定,默认为以 root 身份登录系统并完成同步操作。
rsync 命令提供使用的 OPTION 及功能如表 1 所示。
表 1 rsync 选项及功能
OPTION选项 | 功能 |
-a | 这是归档模式,表示以递归方式传输文件,并保持所有属性,它等同于-r、-l、-p、-t、-g、-o、-D 选项。-a 选项后面可以跟一个 --no-OPTION,表示关闭 -r、-l、-p、-t、-g、-o、-D 中的某一个,比如-a --no-l 等同于 -r、-p、-t、-g、-o、-D 选项。 |
-r | 表示以递归模式处理子目录,它主要是针对目录来说的,如果单独传一个文件不需要加 -r 选项,但是传输目录时必须加。 |
-v | 表示打印一些信息,比如文件列表、文件数量等。 |
-l | 表示保留软连接。 |
-L | 表示像对待常规文件一样处理软连接。如果是 SRC 中有软连接文件,则加上该选项后,将会把软连接指向的目标文件复制到 DEST。 |
-p | 表示保持文件权限。 |
-o | 表示保持文件属主信息。 |
-g | 表示保持文件属组信息。 |
-D | 表示保持设备文件信息。 |
-t | 表示保持文件时间信息。 |
--delete | 表示删除 DEST 中 SRC 没有的文件。 |
--exclude=PATTERN | 表示指定排除不需要传输的文件,等号后面跟文件名,可以是通配符模式(如 *.txt)。 |
--progress | 表示在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、 同步的文件传输速度等。 |
-u | 表示把 DEST 中比 SRC 还新的文件排除掉,不会覆盖。 |
-z | 加上该选项,将会在传输过程中压缩。 |
以上也仅是列出了 async 命令常用的一些选项,对于初学者来说,记住最常用的几个即可,比如 -a、-v、-z、--delete 和 --exclude。
基本用法
-r
参数
本机使用 rsync 命令时,可以作为cp
和mv
命令的替代方法,将源目录同步到目标目录。
rsync -r source destination
上面命令中,-r
表示递归,即包含子目录。注意,-r
是必须的,否则 rsync 运行不会成功。source
目录表示源目录,destination
表示目标目录。
如果有多个文件或目录需要同步,可以写成下面这样。
rsync -r source1 source2 destination
上面命令中,source1
、source2
都会被同步到destination
目录。
-a
参数
-a
参数可以替代-r
,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等)。由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新,所以-a
比-r
更有用。下面的用法才是常见的写法。
rsync -a source destination
目标目录destination
如果不存在,rsync 会自动创建。执行上面的命令后,源目录source
被完整地复制到了目标目录destination
下面,即形成了destination/source
的目录结构。
如果只想同步源目录source
里面的内容到目标目录destination
,则需要在源目录后面加上斜杠。
rsync -a source/ destination
上面命令执行后,source
目录里面的内容,就都被复制到了destination
目录里面,并不会在destination
下面创建一个source
子目录。
-n
参数
如果不确定 rsync 执行后会产生什么结果,可以先用-n
或--dry-run
参数模拟执行的结果。
rsync -anv source/ destination
上面命令中,-n
参数模拟命令执行的结果,并不真的执行命令。-v
参数则是将结果输出到终端,这样就可以看到哪些内容会被同步。
--delete
参数
默认情况下,rsync 只确保源目录的所有内容(明确排除的文件除外)都复制到目标目录。它不会使两个目录保持相同,并且不会删除文件。如果要使得目标目录成为源目录的镜像副本,则必须使用--delete
参数,这将删除只存在于目标目录、不存在于源目录的文件。
rsync -av --delete source/ destination
上面命令中,--delete
参数会使得destination
成为source
的一个镜像。
--exclude
参数
有时,我们希望同步时排除某些文件或目录,这时可以用--exclude
参数指定排除模式。
rsync -av --exclude='*.txt' source/ destination
# 或者
rsync -av --exclude '*.txt' source/ destination
上面命令排除了所有 TXT 文件。
注意,rsync 会同步以"点"开头的隐藏文件,如果要排除隐藏文件,可以这样写--exclude=".*"
。
如果要排除某个目录里面的所有文件,但不希望排除目录本身,可以写成下面这样。
rsync -av --exclude 'dir1/*' source/ destination
多个排除模式,可以用多个--exclude
参数。
rsync -av --exclude 'file1.txt' --exclude 'dir1/*' source/ destination
多个排除模式也可以利用 Bash 的大扩号的扩展功能,只用一个--exclude
参数。
rsync -av --exclude={'file1.txt','dir1/*'} source/ destination
如果排除模式很多,可以将它们写入一个文件,每个模式一行,然后用--exclude-from
参数指定这个文件。
rsync -av --exclude-from='exclude-file.txt' source/ destination
--include
参数
--include
参数用来指定必须同步的文件模式,往往与--exclude
结合使用。
rsync -av --include="*.txt" --exclude='*' source/ destination
上面命令指定同步时,排除所有文件,但是会包括 TXT 文件。
测试例子
#!/bin/bash
keyfile=/home/${USER}/.ssh/slave_ssh_rsa
keyfile_pub=${keyfile}.pub
slave_user=start
slave_ip=172.16.70.18
slave_local_dir=/home/${USER}/ftp/
slave_remote_dir=/home/${slave_user}/temp/
create_login_key(){
echo "create_login_key"
#如果之前未生产过,生成密钥
[ ! -f ${keyfile} ] && ssh-keygen -t rsa -f ${keyfile} -P ''
}
issue_login_key(){
echo "issue_login"
#复制公钥至远程主机
ssh-copy-id -i ${keyfile_pub} -o 'StrictHostKeyChecking=no' ${slave_user}@${slave_ip}
}
sync_files(){
echo "sync_files"
rsync -v -a --delete -e 'ssh -i /home/kms/.ssh/slave_ssh_rsa -o StrictHostKeyChecking=no' ${slave_local_dir} ${slave_user}@${slave_ip}:${slave_remote_dir}
}
read -p "please enter your chioce: 1)setup 2)sync 3)exit " option
case $option in
1)
echo "Current conf is:"
echo "***********************************"
echo "keyfile"
echo "slave_user ${slave_user}"
echo "slave_ip ${slave_ip}"
echo "slave_local_dir ${slave_local_dir}"
echo "slave_user ${slave_user}"
echo "slave_remote_dir ${slave_remote_dir}"
echo "1. Set ssh login without password(Input manual)"
create_login_key
issue_login_key
;;
2)
sync_files
;;
3)
echo "exit"
exit
;;
*)
echo "invalid parameter"
esac
和inotifywait相结合
#!/bin/bash
source=/home/kms/Desktop/inotifywait_shell/source/
#target=/home/kms/Desktop/inotifywait_shell/target/
rysnc_modify(){
# 增改查类型
#rsync -avzc ${source} ${user}@${ip}:${target}
#rsync -avzc ${source} ${target}
slave_user=start
slave_ip=172.16.70.18
slave_local_dir=${source}
slave_remote_dir=/home/${slave_user}/temp/
rsync -v -a --delete -e 'ssh -i /home/kms/.ssh/slave_ssh_rsa -o StrictHostKeyChecking=no' ${slave_local_dir} ${slave_user}@${slave_ip}:${slave_remote_dir}
}
rysnc_del(){
# 删除&移出事件
echo "nothing"
#rsync -avz --delete ${source} ${target}
#rsync -avz --delete ${source} ${user}@${ip}:${target}
}
log_path=./inotifywait.log
/usr/bin/inotifywait -mrq ${source} --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w %f %e' -e create,modify,attrib,move,delete,close_write | while read files;
do
echo "$files" >> ${log_path}
INO_EVENT=$(echo $files | awk '{print $5}')
# 增改查类型
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]] || [[ $INO_EVENT =~ 'ATTRIB' ]]
then
rysnc_modify
fi
# 删除&移出事件
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
rysnc_del
fi
done