对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。这样的话一台一台配置肯定是不现实的,所以,自动同步文件是至关重要的。
而要如何实现自动同步呢?首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。整个过程也称为代码上线。
# yum install -y expect
# vim login.expect #写入下面内容
#! /usr/bin/expect
set host "192.168.33.128" #设置变量
set passwd "19940406" #设置变量
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$passwd\r" }
}
interact #表示停留在远程机器上,而不需要退出,不加interact会退出
# chmod a+x login.expect #给予执行权限
# ./login.expect #运行上面的expect脚本
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Aug 1 13:41:55 2018 from 192.168.33.1
# logout #已经登录到192.168.33.128上
Connection to 192.168.33.128 closed.
# vim login2.expect #写入下面内容
#! /usr/bin/expect
set user "root"
set passwd "19940406"
spawn ssh $user@192.168.33.128
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$passwd\r" }
}
expect "]*" #不管是root提示符还是普通用户,都匹配到
send "touch /tmp/12.txt\r" #执行命令
expect "]*"
send "echo 1212 > /tmp/12.txt\r"
expect "]*"
send "exit\r"
# chmod a+x login2.expect
# ./login2.expect
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Aug 1 13:42:03 2018 from 192.168.33.129
# touch /tmp/12.txt
# echo 1212 > /tmp/12.txt
# [root@localhost sbin]#
# vim login3.expect
#! /usr/bin/expect
set user [lindex $argv 0] #第一个参数的值赋给user
set host [lindex $argv 1] #第二个参数的值赋给host
set passwd "19940406"
set cm [lindex $argv 2] #第三个参数的值赋给cm,表示命令
spawn ssh $user@$host
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
# chmod a+x login3.expect
# ./login3.expect root 192.168.33.128 ls #执行ls命令
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Aug 1 14:00:11 2018 from 192.168.33.129
# ls
anaconda-ks.cfg test.txt zabbix-release-3.4-2.el7.noarch.rpm
# ./login3.expect root 192.168.33.128 "ls;w;vmstat 1 5" #可以执行多个命令,expect默认有超时时间,超过时间就会退出
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Aug 1 15:02:44 2018 from 192.168.33.1
# ls; w; vmstat 1 5
anaconda-ks.cfg test.txt zabbix-release-3.4-2.el7.noarch.rpm
15:06:08 up 1:24, 3 users, load average: 0.03, 0.02, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.33.1 13:41 1:24m 0.01s 0.01s -bash
root pts/1 192.168.33.1 15:02 3:24 0.00s 0.00s -bash
root pts/2 192.168.33.129 15:06 0.00s 0.01s 0.01s w
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 2983248 2076 243576 0 0 10 18 48 47 0 0 100 0 0
0 0 0 2983064 2076 243996 0 0 0 7 219 204 0 0 100 0 0
0 0 0 2983064 2076 243996 0 0 0 136 181 192 0 0 100 0 0
0 0 0 2983064 2076 243996 0 0 0 5 165 170 0 0 100 0 0
0 0 0 2983064 2076 243996 0 0 0 5 205 194 0 0 100 0 0
# vim login4.expect #写入下面内容
#! /usr/bin/expect
set passwd "19940406"
spawn rsync -av [email protected]:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect eof #表示expect脚本结束,如果不加expect eof会导致还没开始传输就会结束
如果想让expect永远不超时,可以在上面添加一行:
set timeout -1 #-1表示永不超时,设置为其它数字就会以其它数字为超时时间,以秒为单位,但是去掉expect eof 仍会出问题
# chmod a+x login4.expect
# ./login4.expect
spawn rsync -av [email protected]:/tmp/12.txt /tmp/
[email protected]'s password:
receiving incremental file list
12.txt
sent 43 bytes received 97 bytes 280.00 bytes/sec
total size is 5 speedup is 0.04
# cat /tmp/12.txt
1212
# vim login5.expect #写入下面内容
#! /usr/bin/expect
set passwd "19940406"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "$yes\r" }
"password:" { send "$passwd\r" }
}
expect eof
# chmod a+x login5.expect
# ./login5.expect 192.168.33.128 "/tmp/12.txt" //将本地文件同步到远程,只适合同时同步一个文件
spawn rsync -av /tmp/12.txt [email protected]:/tmp/12.txt
[email protected]'s password:
sending incremental file list
sent 45 bytes received 12 bytes 114.00 bytes/sec
total size is 5 speedup is 0.09
将本地文件同步到远程,只适合同时同步一个文件。
rsync -av --files-from=list.txt / root@host:/ #文件路径必须是绝对路径
# vim rsync.expect #写入下面内容
#! /usr/bin/expect
set passwd "19940406"
set host [lindex $argv 0]
set file [lindex $argv 1] #指的是list.txt ,表示一个列表而不仅仅是一个文件
spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
export eof
file.list
:# vim /tmp/file.list #写入下面内容
/tmp/12.txt
/tmp/1.txt
/tmp/2.txt
/tmp/3.txt
/tmp/111/111.txt
ip.list
:# vim /tmp/ip.list #写入下面内容
192.168.33.128
127.0.0.1
rsync.sh
:# vim rsync.sh #写入下面内容
#! /bin/bash
for ip in `cat /tmp/ip.list`
do
./rsync.expect $ip /tmp/file.list
done
# chmod a+x rsync.expect
# sh rsync.sh
spawn rsync -av --files-from=/tmp/file.list / [email protected]:/
[email protected]'s password:
building file list ... done
tmp/
tmp/1.txt
tmp/2.txt
tmp/3.txt
tmp/111/
tmp/111/111.txt/
sent 311 bytes received 82 bytes 262.00 bytes/sec
total size is 5 speedup is 0.01 //192.168.33.128传输成功
spawn rsync -av --files-from=/tmp/file.list / [email protected]:/
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. #127.0.0.1出现问题,暂且不用管
ECDSA key fingerprint is SHA256:y/jrhxRLVYWO6YhN5a2DSQePmWH3CCVWcV578JDKbPg.
ECDSA key fingerprint is MD5:1b:86:bc:80:c5:c6:14:7a:4f:6c:29:b4:14:8f:86:d1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
# ls -l /tmp/
总用量 4
drwxr-xr-x 3 root root 21 8月 1 14:47 111
-rw-r--r-- 1 root root 5 8月 1 14:00 12.txt
-rw-r--r-- 1 root root 0 8月 1 14:47 1.txt
-rw-r--r-- 1 root root 0 8月 1 14:47 2.txt
-rw-r--r-- 1 root root 0 8月 1 14:47 3.txt
有时候我们在批量传输完文件还不够,还需要在目标机器上执行命令来操作一些服务,这时候就需要对机器进行命令的批量执行。
exe.expect
:# vim exe.expect #写入下面内容
#! /usr/bin/expect
set host [lindex $argv 0]
set passwd "19940406"
set cm [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r" }
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
exe.sh
:# vim exe.sh #写入下面内容
#! /bin/bash
for ip in `cat /tmp/ip.list`
do
./exe.expect $ip "hostname"
done
# chmod a+x exe.expect
# sh exe.sh
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Aug 1 15:06:08 2018 from 192.168.33.129
# hostname
localhost.localdomain #192.168.33.128主机名
# spawn ssh [email protected]
[email protected]'s password:
Last failed login: Wed Aug 1 15:17:30 CST 2018 from 127.0.0.1 on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Wed Aug 1 13:54:06 2018 from 192.168.33.1
# hostname
localhost.localdomain #127.0.0.1本地主机名
更多资料参考:
Shell脚本学习之expect命令
linux expect 使用