五、自动同步文件

5.1 配置脚本

核心命令,就是用的rsync服务。

[root@xavilinux03 sbin]# vim 4.expect
#!/usr/bin/expect
set passwd "123456"
spawn rsync -av root@192.168.XXX.XXX:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof

5.2 授权并测试

# chmod a+x 4.expect 

[root@xavi sbin]# ./4.expect
spawn rsync -avR  //加上-R是为了便于在连接的主机上没有相同文件路径时,自动创建
root@116.62.XXX.XXX:/tmp/12.txt /tmp/
root@116.62.XXX.XXX's password: 
receiving incremental file list
tmp/
tmp/12.txt

sent 34 bytes  received 115 bytes  298.00 bytes/sec
total size is 5  speedup is 0.03

如上可以看出 已经成功的同步了文件。

expect eof 的作用

脚本中,如果我们不加此语句,一旦登录成功就会退出。

在这里加入set timeout替代expect eof是无效的

六、指定host和要同步的文件

6.1 脚本配置

vim 5.expect

#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]  //第一个参数是host,ip
set file [lindex $argv 1]  //第二个参数是文件,file是绝对路径
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof

脚本目的是:推送一个本地文件到远程服务器。

6.2 授权

# chmod a+x 5.expect

我现在尝试把我本地的一个文件推送到服务器:文件内容如下:

# cat /tmp/users.txt 
username: user_9 password: 1zg^NIx7on
username: user_5 password: e21oHjeYg=
username: user_6 password: e21oHjeYg=
username: user_7 password: e21oHjeYg=
username: user_8 password: e21oHjeYg=
username: user_5 password: gNR0o{1qjw
username: user_6 password: Pam1lxsN6[
username: user_7 password: 6hd5p^XgwM
username: user_8 password: kvcoyJ5_G0
username: user_5 password: is0wb*SNj7
username: user_6 password: BEgg89qgz<
username: user_7 password: Nxvt8-xGw8
username: user_8 password: 6mpbk5sDS-

6.3 执行,脚本+host地址+文件(绝对路径)

# ./5.expect 192.168.XXX.XXX "/tmp/users.txt"  

spawn rsync -av /tmp/users.txt root@192.168.72.132:/tmp/users.txt
root@192.168.72.132's password: 
sending incremental file list
users.txt

sent 571 bytes  received 31 bytes  1204.00 bytes/sec
total size is 494  speedup is 0.82

6.4 去远程服务器上查看

[root@xavi ~]# cat /tmp/users.txt 
username: user_9 password: 1zg^NIx7on
username: user_5 password: e21oHjeYg=
username: user_6 password: e21oHjeYg=
username: user_7 password: e21oHjeYg=
username: user_8 password: e21oHjeYg=
username: user_5 password: gNR0o{1qjw
username: user_6 password: Pam1lxsN6[
username: user_7 password: 6hd5p^XgwM
username: user_8 password: kvcoyJ5_G0
username: user_5 password: is0wb*SNj7
username: user_6 password: BEgg89qgz<
username: user_7 password: Nxvt8-xGw8
username: user_8 password: 6mpbk5sDS-

已经成功推送!!!

但是这只是开始,一般我们推送一个软件或者上线一个服务肯定不是一个文件就可以的。所以我们需要的是大量的文件子目录+脚本推送。

七、文件分发系统实现

7.1 需求背景

  • [ ] 对于大公司而言,经常会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。 实现思路:

  • [ ] 首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。

7.2 核心命令:rsync -av --files-from=list.txt / root@host:/

注意这里的都是根目录

7.3 脚本配置

vim rsync.expect
#!/usr/bin/expect
set passwd "123456"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof

核心命令:
rsync -av –files-from=$file / root@$host:/:上传文件的列表是$file,我们需要在list当中去定义 哪些目录或文件是我们需要同步更新上线的。

7.4 文件列表

[root@xavi sbin]# !vim
vim /tmp/list.txt

/tmp/12.txt
/root/for01.sh
/root/temp/test.txt
  • [ ] 假如我们需要同步如上3个文件,前提是一定要保证对方的server一定也要有这个目录,例如: /tmp/ /user/local/sbin/ /tmp/, 不然同步会出错。(如上脚本中我们添加了 rsync -avR R就是自动创建级联的目录。)

7.5 IP列表

[root@xavi sbin]# vim /tmp/ip.list

192.168.72.133
127.0.0.1

有一个重要的前提就是:所有的机器必须要保证有着相同的密码。但是这样操作有点危险,一旦文档泄露就比较麻烦了。所以我们会选择针对需要同步的服务器进行密钥认证。一旦密钥认证后,如下脚本中的语句我们就可以省略:

"password:" { send "$passwd\r" }

第二种方法就是:逐一修改密码

[root@xavi sbin]# passwd
更改用户 root 的密码 。
新的 密码:
重新输入新的 密码:

passwd:所有的身份验证令牌已经成功更新。

7.6 创建一个rsync的shell脚本

脚本的目的:遍历所有的server和list中的文件可以同步到每台服务器。

[root@xavi sbin]# vim rsync.sh

#!/bin/bash

for ip in `cat /tmp/ip.list`
do
    echo $ip
    ./rsync.expect $ip /tmp/list.txt
done

7.7 授权并测试:

[root@xavi sbin]# sh -x rsync.sh
++ cat /tmp/ip.list
+ for ip in '`cat /tmp/ip.list`'
+ echo 116.62.XXX.XXX
116.62.XXX.XXX
+ ./rsync.expect 116.62.XXX.XXX /tmp/list.txt
spawn rsync -avR --files-from=/tmp/list.txt / root@116.62.XXX.XXX:/
root@116.62.XXX.XXX's password: 
building file list ... done
root/
root/for01.sh
root/temp/
root/temp/test.txt
tmp/
tmp/12.txt

sent 622 bytes  received 84 bytes  1412.00 bytes/sec
total size is 339  speedup is 0.48
+ for ip in '`cat /tmp/ip.list`'
+ echo 127.0.0.1
127.0.0.1
+ ./rsync.expect 127.0.0.1 /tmp/list.txt
spawn rsync -avR --files-from=/tmp/list.txt / root@127.0.0.1:/
root@127.0.0.1's password: 
building file list ... done

sent 145 bytes  received 12 bytes  314.00 bytes/sec
total size is 339  speedup is 2.16 

八、批量远程执行命令

有时候当我们传输同步完毕之后,可能需要重启一下nginx服务,或者mysql服务,这样就用到了远程执行命令。

8.1 脚本配置

vim exe.expect

#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "123456"
set cm [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
  • [ ] set host [lindex $argv 0]:第一个参数

  • [ ] set cm [lindex $argv 1]:第二个参数

8.2 expect脚本授权

chmod a+x exe.expect

8.3 定义exe的shell脚本

[root@xavi sbin]# vim exe.sh

#!/bin/bash

for ip in `cat ip.list`
do
echo $ip
./exe.expect $ip "w;free -m;ls /tmp"
done

mark

8.4 登陆到了定义的远程server,并且执行了相关的命令!

[root@xavi sbin]# sh -x exe.sh
++ cat ip.list
+ for ip in '`cat ip.list`'
+ echo 116.62.xxx.xxx
116.62.xxx.xxx
+ ./exe.expect 116.62.xxx.xxx 'w;free -m;ls /tmp'
spawn ssh root@116.62.xxx.xxx
root@116.62.xxx.xxx's password: 
Last login: Tue May  1 09:06:02 2018 from 117.80.xxx.xxx

Welcome to Alibaba Cloud Elastic Compute Service !

[root@xaviyunserver ~]# w;free -m;ls /tmp
 10:42:43 up  2:44,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    117.60.xxx.xxx  08:01    2:01m  0.00s  0.00s -bash
root     pts/1    117.80.xxx.xxx    09:06   13:47   0.00s  0.00s -bash
root     pts/2    117.80.xxx.xxx    10:42    0.00s  0.00s  0.00s w
              total        used        free      shared  buff/cache   available
Mem:           1839          63        1403           0         372        1628
Swap:             0           0           0
12.txt
Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>
systemd-private-791e0c77625c4133bda4340fcd191439-ntpd.service-mZ3IQT
[root@xaviyunserver ~]# + for ip in '`cat ip.list`'
+ echo 127.0.0.1
127.0.0.1
+ ./exe.expect 127.0.0.1 'w;free -m;ls /tmp'
spawn ssh root@127.0.0.1
root@127.0.0.1's password: 
Last failed login: Tue May  1 10:01:00 CST 2018 from localhost on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Tue May  1 09:06:00 2018 from 192.168.72.1
[root@xavi ~]# w;free -m;ls /tmp
 10:42:43 up  7:26,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     07:52    1:59m  0.44s  0.44s -bash
root     pts/1    192.168.72.1     09:06    3.00s  2.19s  0.01s /usr/bin/expect ./exe.expect 127.0.0.1 w;
root     pts/3    localhost        10:42    0.00s  0.04s  0.00s w
              total        used        free      shared  buff/cache   available
Mem:           1823         243        1114          17         465        1364
Swap:          3813           0        3813
12.txt
ip.list
list.txt
php-fcgi.sock
systemd-private-59132022d890457896ed0047dcd941fe-cups.service-rfy8W2
systemd-private-59132022d890457896ed0047dcd941fe-httpd.service-h5dZDM
systemd-private-59132022d890457896ed0047dcd941fe-vmtoolsd.service-iZ3m2r
tmp
xavier.sock