expect脚本同步文件、expect脚本指定host和要同步的文件、构建文件分发系统、批量远程执行命令
7月20日任务
20.31 expect脚本同步文件
20.32 expect脚本指定host和要同步的文件
20.33 构建文件分发系统
20.34 批量远程执行命令
扩展:
shell多线程 http://blog.lishiming.net/?p=448
20.31 expect脚本同步文件
使用expect脚本实现在一台机器上把文件同步到另外一台机器上,这里需要用到核心命令rsync,如果是手动方式进行同步,那么还需要单独输入密码,所以没有脚本方式操作方便。
示例:自动同步文件
[root@jimmylinux-001 sbin]# vi 4.expect
#!/usr/bin/expect
set passwd "***@126.com"
spawn rsync -av root@192.168.52.129:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof 如果不加这条语句,那么还没有开始执行数据传输,就马上结束了,甚至有可能还没有远程登录成功,就已经退出来了,所以脚本里面必须要加这条语句。
执行效果
1 [root@jimmylinux-001 sbin]# chmod a+x 4.expect
2 [root@jimmylinux-001 sbin]# ./4.expect
3 spawn rsync -av root@192.168.52.129:/tmp/12.txt /tmp/
4 root@192.168.52.129's password:
5 receiving incremental file list
6 12.txt
7
8 sent 43 bytes received 96 bytes 92.67 bytes/sec
9 total size is 5 speedup is 0.04
10 [root@jimmylinux-001 sbin]# cat /tmp/12.txt
11 1212
20.32 expect脚本指定host和要同步的文件
之前的3.expect文件默认是10秒钟超时,当然也是可以增加超时时间甚至可以让永久不超时。
只需要在脚本文件中添加第3行set timeout语句即可
1 expect "]*"
2 send "$cm\r"
3 set timeout 3 设置超时秒数,如果是-1表示永久不会超时
4 expect "]*"
5 send "exit\r"
示例:指定host和要同步的文件,这种方式只适合同步一个文件。
1 [root@jimmylinux-001 sbin]# vi 5.expect
2
3 #!/usr/bin/expect
4 set passwd "***@126.com"
5 set host [lindex $argv 0] 第一个变量是主机host(也就是主机IP地址)
6 set file [lindex $argv 1] 第二个变量是要同步的文件
7 spawn rsync -av $file root@$host:$file 这里是从本机到对方,而且file要写绝对路径。
8 expect {
9 "yes/no" { send "yes\r"}
10 "password:" { send "$passwd\r" }
11 }
12 expect eof
执行效果
1 [root@jimmylinux-001 sbin]# chmod a+x 5.expect
2 [root@jimmylinux-001 sbin]# ./5.expect 192.168.52.129 "/tmp/12.txt"
3 spawn rsync -av /tmp/12.txt root@192.168.52.129:/tmp/12.txt
4 root@192.168.52.129's password:
5 sending incremental file list
6
7 sent 44 bytes received 12 bytes 112.00 bytes/sec
8 total size is 5 speedup is 0.09
20.33 构建文件分发系统
需求背景:对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
实现思路:首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。
核心命令:rsync -av --files-from=list.txt / root@host:/
文件分发系统的实现
1、编写 rsync.expect
1 [root@jimmylinux-001 sbin]# vi rsync.expect
2
3 #!/usr/bin/expect
4 set passwd "***@126.com"
5 set host [lindex $argv 0]
6 set file [lindex $argv 1]
7 spawn rsync -avR --files-from=$file / root@$host:/ 如果不确定对方机器有相同的路径,可以加-avR
8 expect {
9 "yes/no" { send "yes\r"}
10 "password:" { send "$passwd\r" }
11 }
12 expect eof
2、编写文件列表 file.list
1 [root@jimmylinux-001 sbin]# vi /tmp/file.list
2
3 /tmp/12.txt
4 /tmp/666.txt
5 /root/shell/01.sh
3、编写IP地址列表文件 ip.list
1 [root@jimmylinux-001 sbin]# vi /tmp/ip.list
2
3 192.168.52.129
4 192.168.52.130
4、创建 rsync.sh shell文件
1 [root@jimmylinux-001 sbin]# vi rsync.sh
2
3 #!/bin/bash
4 for ip in `cat /tmp/ip.list`
5 do
6 ./rsync.expect $ip /tmp/file.list
7 done
执行效果
1 [root@jimmylinux-001 sbin]# chmod a+x rsync.expect
2 [root@jimmylinux-001 sbin]# sh -x rsync.sh
3 ++ cat /tmp/ip.list
4 + for ip in '`cat /tmp/ip.list`'
5 + ./rsync.expect 192.168.52.129 /tmp/file.list
6 spawn rsync -avR --files-from=/tmp/file.list / root@192.168.52.129:/
7 root@192.168.52.129's password:
8 building file list ... done
9 root/
10 root/shell/
11 root/shell/01.sh
12 tmp/
13 tmp/666.txt
14
15 sent 295 bytes received 63 bytes 238.67 bytes/sec
16 total size is 39 speedup is 0.11
17 + for ip in '`cat /tmp/ip.list`'
18 + ./rsync.expect 192.168.52.130 /tmp/file.list
19 spawn rsync -avR --files-from=/tmp/file.list / root@192.168.52.130:/
20 The authenticity of host '192.168.52.130 (192.168.52.130)' can't be established.
21 ECDSA key fingerprint is SHA256:i7B62YOT5sTvxaFu5nD0ETjwadiNfG/RVEb9F/Eh1Nw.
22 ECDSA key fingerprint is MD5:b9:6f:1e:01:0e:5b:bc:69:96:b4:5b:f1:cf:de:b0:5f.
23 Are you sure you want to continue connecting (yes/no)? yes
24 Warning: Permanently added '192.168.52.130' (ECDSA) to the list of known hosts.
25 root@192.168.52.130's password: [root@jimmylinux-001 sbin]#
26 [root@jimmylinux-001 sbin]#
在192.168.52.129机器上,可以查看到刚才远程同步的3个文件。
1 [root@jimmylinux-002 ~]# ls -l /tmp/
2
3 -rw-r--r-- 1 root root 5 7月 19 22:56 12.txt
4 -rw-r--r-- 1 root root 5 7月 22 15:20 666.txt
1 [root@jimmylinux-002 ~]# ls -l /root/shell/
2
3 -rwxr-xr-x 1 root root 29 7月 12 22:26 01.sh
20.34 批量远程执行命令
想批量远程执行命令,可以通过2个脚本来实现。
1、创建 exe.expect 脚本
1 [root@jimmylinux-001 sbin]# vi exe.expect
2
3 #!/usr/bin/expect
4 set host [lindex $argv 0]
5 set passwd "***@126.com"
6 set cm [lindex $argv 1]
7 spawn ssh root@$host
8 expect {
9 "yes/no" { send "yes\r"}
10 "password:" { send "$passwd\r" }
11 }
12 expect "]*"
13 send "$cm\r"
14 expect "]*"
15 send "exit\r"
2、添加执行权限
[root@jimmylinux-001 sbin]# chmod a+x exe.expect
3、创建 exe.sh shell脚本
1 [root@jimmylinux-001 sbin]# vi exe.sh
2
3 #!/bin/bash
4 for ip in `cat /tmp/ip.list`
5 do
6 ./exe.expect $ip "hostname"
7 done
执行效果
1 [root@jimmylinux-001 sbin]# sh exe.sh
2 spawn ssh root@192.168.52.129
3 root@192.168.52.129's password:
4 Last login: Sun Jul 22 15:34:50 2018 from 192.168.52.1
5
6 [root@jimmylinux-002 ~]# hostname
7 jimmylinux-002
8 [root@jimmylinux-002 ~]# spawn ssh root@192.168.52.130
9 root@192.168.52.130's password:
10 Last failed login: Sun Jul 22 15:32:17 CST 2018 from 192.168.52.128 on ssh:notty
11 There were 2 failed login attempts since the last successful login.
12 Last login: Sun Jul 8 14:21:45 2018 from 192.168.52.1
13
14 hostname
15 [root@jimmylinux-003 ~]# hostname
16 [root@jimmylinux-001 sbin]#