出自http://c.biancheng.net/view/6121.html

在 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 命令时,可以作为cpmv命令的替代方法,将源目录同步到目标目录。

rsync -r source destination

上面命令中,-r表示递归,即包含子目录。注意,-r是必须的,否则 rsync 运行不会成功。source目录表示源目录,destination表示目标目录。

如果有多个文件或目录需要同步,可以写成下面这样。

 rsync -r source1 source2 destination

 上面命令中,source1source2都会被同步到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

 

posted on 2022-02-25 10:34  陌鉎こ城sHi  阅读(544)  评论(0编辑  收藏  举报