每天一个linux命令:拷贝命令家族(cp、scp、rsync) --- rsync

每天一个linux命令:拷贝命令家族(cp、scp、rsync) — rsync

1. rsync功能

rsync — remote sync,rsync是Linux系统下的文件同步和数据传输工具,可以将一个客户机和远程文件服务器之间的文件同步,也可以在本地系统中将数据从一个分区备份到另一个分区上。如果rsync在备份过程中出现了数据传输中断,恢复后可以继续传输不一致的部分。rsync可以执行完整备份或增量备份,只同步有改变的部分,所以比scp命令更高效,但是rsync本身是一种非加密的传输,如果要进行加密传输可以使用“-e”选项来设置具备加密功能的承载工具进行加密传输。

主要特点有:

  • 可以镜像保存整个目录树和文件系统;
  • 可以很容易做到保持原来文件的权限、时间、软硬链接;无须特殊权限即可安装;
  • 可以增量同步数据,文件传输效率高,因而同步时间短;
  • 可以使用rcp、ssh等方式来传输文件,当然也可以通过直接的socket连接;
  • 支持匿名传输,以方便进行网站镜象等;
  • 加密传输数据,保证了数据的安全性;

如果实验ssh方式加密传输,使用rsync命令之前要保证服务端开启了ssh server。

更多精彩请关注:www.zicreate.com

2.命令格式

rsync [OPTION]... SRC DEST
rsync [OPTION]... SRC [USER@]HOST:DEST
rsync [OPTION]... [USER@]HOST:SRC DEST
rsync [OPTION]... [USER@]HOST::SRC DEST
rsync [OPTION]... SRC [USER@]HOST::DEST
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]

对应于以上六种命令格式,rsync有六种不同的工作模式:

  • a. 拷贝本地文件。当SRC和DES路径信息都不包含有单个冒号”:”分隔符时就启动这种工作模式。如:rsync -a /data /backup
  • b. 使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DST路径地址包含单个冒号”:”分隔符时启动该模式。如:rsync -avz *.c foo:src
  • c. 使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号”:”分隔符时启动该模式。如:rsync -avz foo:src/bar /data
  • d. 从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含”::”分隔符时启动该模式。如:rsync -av [email protected]::www /databack
  • e. 从本地机器拷贝文件到远程rsync服务器中。当DST路径信息包含”::”分隔符时启动该模式。如:rsync -av /databack [email protected]::www
  • f. 列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。如:rsync -v rsync://192.168.78.192/www

3.主要命令参数

-v, --verbose 详细模式输出
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-r, --recursive 对子目录以递归模式处理
-R, --relative 使用相对路径信息
-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。
--backup-dir 将备份文件(如~filename)存放在在目录下。
-suffix=SUFFIX 定义备份文件前缀
-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)
-l, --links 保留软链结
-L, --copy-links 想对待常规文件一样处理软链结
--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结
--safe-links 忽略指向SRC路径目录树以外的链结
-H, --hard-links 保留硬链结
-p, --perms 保持文件权限
-o, --owner 保持文件属主信息
-g, --group 保持文件属组信息
-D, --devices 保持设备文件信息
-t, --times 保持文件时间信息
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间
-n, --dry-run现实哪些文件将被传输
-W, --whole-file 拷贝文件,不进行增量检测
-x, --one-file-system 不要跨越文件系统边界
-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节
-e, --rsh=COMMAND 指定使用rsh、ssh方式进行数据同步
--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息
-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件
--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件
--delete 删除那些DSTSRC没有的文件
--delete-excluded 同样删除接收端那些被该选项指定排除的文件
--delete-after 传输结束以后再删除
--ignore-errors 及时出现IO错误也进行删除
--max-delete=NUM 最多删除NUM个文件
--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输
--force 强制删除目录,即使不为空
--numeric-ids 不将数字的用户和组ID匹配为用户名和组名
--timeout=TIME IP超时时间,单位为秒
-I, --ignore-times 不跳过那些有同样的时间和长度的文件
--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间
--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0
-I 为所有更新输出一个更改摘要
-T --temp-dir=DIRDIR中创建临时文件
--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份
-P 等同于 --partial
--progress 显示备份过程
-z, --compress 对备份的文件在传输时进行压缩处理
--exclude=PATTERN 指定排除不需要传输的文件模式
--include=PATTERN 指定不排除而需要传输的文件模式
--exclude-from=FILE 排除FILE中指定模式的文件
--include-from=FILE 不排除FILE指定模式匹配的文件
--version 打印版本信息
--address 绑定到特定的地址
--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件
--port=PORT 指定其他的rsync服务端口
--blocking-io 对远程shell使用阻塞IO
-stats 给出某些文件的传输状态
--progress 在传输时现实传输过程
--log-format=formAT 指定日志文件格式
--password-file=FILEFILE中得到密码
--bwlimit=KBPS 限制I/O带宽,KBytes per second
-h, --help 显示帮助信息

4.使用场景

rsync 的工作模式很多,支持本地同步,但是最常用的还是工作机与服务器之间的文件同步,下面着重介绍远程同步功能。

场景1:从本地复制到远程

我有一段时期的工作是进行Linux 显卡驱动的 backport,需要将驱动移植到各种OS上,而不同 OS 的或同一个OS的不同版本 kernel 是不一样的,虽然可以通过硬盘分区保证工作数据稳定,但是由于版本太多,总有时候需要格式化整个硬盘,所以,我至少有2台电脑可用,一台作为开发机,一台作为服务器。

开发机可以随便折腾,而服务器专门用来保存各种工作文档。每次在工作机上产生结果性的文档都会将文件通过rsync同步到服务器上;同样,当开发机重新安装OS后也会将服务器的文档同步回开发机。

后来,我的另一个工作中管理的电脑数量更大了,程序迭代过程中不定时的需要将最新的程序部署到几十台电脑中,rsync 依然是我最喜欢的操作方式。

命令:

将workspace 目录传输到远程 /tmp/目录下。

$ rsync -arvz --progress workspace [email protected]:/tmp/
root@10.239.85.234's password:
sending incremental file list
workspace/
workspace/pingtime.py
        4265 100%    0.00kB/s    0:00:00 (xfer#1, to-check=14/21)
workspace/rpc_client.py
       12052 100%   11.49MB/s    0:00:00 (xfer#2, to-check=8/21)
workspace/transfromaton_file2config.py
        5943 100%    2.83MB/s    0:00:00 (xfer#3, to-check=4/21)

sent 10358 bytes  received 74 bytes  2980.57 bytes/sec
total size is 149791  speedup is 14.36

请注意!在上面的实例中,我指定的目录名“workspace” 后面没有跟 “/”,这种情况下会在远程目录“/tmp/”下创建同名目录“workspace”。但是如果,我使用参数“workspace/”,那么会将“workspace”目录内的内容全部传输到指定目录,而不会创建同名文件夹!

使用参数“workspace/”结果如下:

$ rsync -arvz --progress workspace/ root@10.239.85.234:/tmp/testdir
root@10.239.85.234's password:
sending incremental file list
./
README.md
        6071 100%    0.00kB/s    0:00:00 (xfer#1, to-check=19/21)
...省略其他...
sent 52900 bytes  received 380 bytes  11840.00 bytes/sec
total size is 149791  speedup is 2.81

总结:rsync命令使用中,如果源参数的末尾有斜线“/”,只会复制指定目录的内容,而不复制目录本身;如果没有斜线,则会复制目录本身,包括目录。

场景2:从远程复制到本地

场景1与场景2的操作是一样的,唯一的区别仅在于 [源路径] [目标路径] 的定义不同而已,不再详述。

场景3:传输时显示变化的文件

$ rsync -avzi --out-format='%i %n%L' workspace/ root@10.239.85.234:/tmp/testdir
root@10.239.85.234's password:
sending incremental file list
.d..t...... ./
<f.st...... config.ini
<f.st...... report-20171130024526.txt
.d..t...... cfg/
<f.st...... cfg/power_record.json

sent 988 bytes  received 94 bytes  144.27 bytes/sec
total size is 149791  speedup is 138.44

上面上命令在将本地文件同步到远程时会为所有更新输出一个更改摘要。更详细的解释可以参考man手册。

场景4:rsyncd 模式的使用

上面的场景中,我们能够随意进行文件、目录的备份与恢复;服务器是我自己的,有帐号、密码控制,并且在企业内部使用,所以,我不需要太关心安全性问题,上面那些场景已经能满足我几乎全部的需求了。

但是,接下来我们考虑另一个场景:
服务器是Team内大家公用的,作为管理员,我们不希望大家太随意,因为太随意不仅影响数据安全性,并且久而久之服务器内的文件必然乱七八糟的无法维护。但是,我们又需要分配给不同的人一定的备份、访问权限,保证项目文件都能及时汇总在一块,并且能被需要的人员查看。当然,要满足这个需求有很多版本管理工具,但是我不打算分析各个工具的区别以及优缺点,下面我们只讨论如何用rsync实现这一目标。

没错,我们需要的就是rsyncd 。

启动 rsyncd 的方式就是在服务器上启动 rsync 时加上特定的几个参数:

$ rsync –daemon –config=/etc/rsyncd.conf

没错,就这么简单。

那么“–config=/etc/rsyncd.conf“ 是什么? 它就是rsync头上的紧箍咒,保证rsync不再那么任性。

(1) 文件准备

查看自己的电脑的/etc/目录下是否有如下文件,如果没有的话创建即可(touch是创建命令):

$ touch /etc/rsyncd.conf           #主配置文件
$ touch /etc/rsyncd.secrets       #用户名密码文件,一组用户一行,用户名和密码使用 : 分割
$ touch /etc/rsyncd.motd          #非必须,连接上rsyncd显示的欢迎信息,此文件可不创建

必须注意的是,rsyncd.secrets 密码文件权限必须是600!

chmod 0600 /etc/rsyncd.secrets

编辑主配置文件 rsyncd.conf:

######################################################################################################
#                      ******进程相关全局配置******
######################################################################################################
#    pid file 守护进程pid文件
pid file=/var/run/rsyncd.pid
#日志相关
#    log file 指定rsync发送消息日志文件,而不是发送给syslog,如果不填这个参数默认发送给syslog
#    transfer logging 是否记录传输文件日志
#    log format 日志文件格式
#    syslog facility rsync发送消息给syslog时的消息级别,
#    timeout连接超时时间
log file=/var/log/rsyncd.log
transfer logging = yes
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300

#  注:指定运行端口,默认是873,您可以自己指定;
port = 873
# 服务器端传输文件时,要发哪个用户和用户组来执行,默认是nobody。 用户可以自己指定,我这里直接使用root。
# 用户名必须是本地系统中存在的用户名
uid = root
gid = root
# 建议允许 chroot 提升安全性,yes 时收到连接会首先chroot到模块path参数指定的目录下,这样做的好处是可能保护系统被安装漏洞侵袭的可能。缺点是需要 root 用户权限。另外对符号链接文件,将会排除在外。也就是说,你在 rsync服务器上,如果有符号链接,你在备份服务器上运行客户端的同步数据时,只会把符号链接名同步下来,并不会同步符号链接的内容;
# chroot为yes时必须使用root权限。
use chroot = yes
#只读
read only = no
#只写
write only = no
#允许访问rsyncd服务的ip,ip端或者单独ip之间使用空格隔开,也可以为模块单独指定hosts allow
hosts allow = 10.239.85.0/24
#不允许访问rsyncd服务的ip,*是全部(不涵盖在hosts allow中声明的ip,注意和hosts allow的先后顺序)
hosts deny = *
#客户端最大连接数
max connections = 5
#欢迎文件路径,可选的
motd file = /etc/rsyncd.motd


######################################################################################################
#                      ******模块配置(多个)******
######################################################################################################
#模块 模块名称必须使用[]环绕,比如要访问data1,则地址应该是[email protected]::data1
[workspace]
    #模块根目录,必须指定
    path=/home/test
    #是否允许列出模块里的内容
    list=yes
    #忽略错误
    #ignore errors
    #默认情况下,client端不需要使用用户名密码。如果希望client使用特定的用户名,密码,可以增加类似下配置
    #多个用户名由空格或逗号分隔。这里的用户和系统用户没有任何关系。
    auth users = user1, user2,
    #模块验证密码文件 可放在全局配置里
    #用户的名和密码以明文方式存放在”secrets file”选项指定的文件中。
    #文件每行包含一个username:passwd对,passwd不要超过8个字符。
    secrets file=/etc/rsyncd.secrets
    #注释
    comment = some description about this moudle
    #排除目录,多个之间使用空格隔开
    exclude = test1/ test2/

[browser]
    auth users = zicreate, user2,
    path = /tmp/www
    hosts allow = 10.239.85.0/24

编辑密码文件 rsyncd.secrets :

root:123456
user1:12345
user2:abcdef
zicreate:123456

编辑欢迎文件rsyncd.motd:

欢迎来到知创学院(www.zicreate.com),学习交流物联网及智能硬件开发的相关技术及经验!

说明:即便已经启动了rsyncd,修改上面的三个配置文件也会被rsyncd自动感知。

(2)在客户端测试

$ rsync  --list-only  user1@10.239.85.241::
欢迎来到知创学院(www.zicreate.com),学习交流物联网及智能硬件开发的相关技术及经验!

workspace       some description about this moudle

$ rsync  --list-only  zicreate@10.239.85.241::workspace
欢迎来到知创学院(www.zicreate.com),学习交流物联网及智能硬件开发的相关技术及经验!

Password:
drwxr-xr-x        4096 2017/12/11 04:37:11 .
-rw-r--r--         288 2017/10/18 05:43:27 config.ini
-rw-r--r--        1673 2017/10/18 05:28:23 file_receive.py
-rw-r--r--        1385 2017/10/18 05:11:33 file_send.py
drwxr-xr-x        4096 2017/12/11 03:25:20 work-0.2a


#备份文件夹到本地:

$ rsync -r user1@10.239.85.241::workspace ./
...此处省略过程...
注意: 上面的命令由于要同步的是workspace 整个文件夹,所以,必须添加-r参数,否则会出错!

配置好上面的一切之后,我们再来试试还能不能任性的还原、备份了:

$ rsync -r root@10.239.85.241:/tmp/zicreate ./             #注: 目录/tmp/zicreate 实际存在
success

如上所示,如果我们使用系统级的用户名以及密码依然能任性的备份、拷贝。
结论:

  • rsyncd 只限制了 “[USER@]HOST::” 这种指令的访问范围。而[USER@]HOST:“”这样的指令并不受限制。
  • 如果我们不公开我们的系统级用户名及密码,而使用文件 rsyncd.secrets 中定义的用户名和密码,这种情况下才能达到访问控制的目的。
  • “[USER@]HOST::” 这种指令对应 rsyncd 模式。

场景5:自动文件备份

为了实现定时备份,可以将rsync 与crontab 配合使用,或者更简单的方法写一个脚本每隔一定时间同步一次。同时,自动备份时需要解决自动输入密码的问题,这个可以使用expect 解决,具体实现如下所示:

注: 本例为了简化问题将密码直接写在了文件中,实际使用时最好将密码写入临时环境变量中。

#!/bin/bash

passwd=12345

/usr/bin/expect << EOF
set time 100
spawn rsync -avzr user1@10.239.85.241::workspace  workspace
expect {
    "*assword:" {
        send "$passwd\r"
        exp_continue
    }

    "yes/no)?" {
        send "yes\r"
        exp_continue
    }

    timeout {
        close
        break
    }

    eof {
        exit 0
    }
}
interact
EOF

crontab 、expect 、iptables 防火墙、chroot、环境变量配置密码以及脚本开机启动等将在后面慢慢讲解,毕竟每一个都不简单。

本文到此结束。

扩展

Linux 防火墙是用iptables,所以如果防火墙限制了我们对 rsync 服务端口的访问,可以通过修改防火墙路由规则处理(服务器、客户端都需要开发该端口)。处理方法如下:

#iptables -A INPUT -p tcp -m state --state NEW  -m tcp --dport 873 -j ACCEPT
#iptables -L  查看一下防火墙是不是打开了 873端口

在实验阶段甚至可以直接关闭防火墙:

# service firewalld stop

最后:rsync 功能非常复杂,本文属于入门教程,更多高级、复杂运用请参考:http://rsync.samba.org/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章