20.31 expect脚本同步文件


目的:在expect脚本上实现,在一台机器上把文件同步到另一台机器上面去。

核心命令:#rsync,在脚本使用rsync对比起在系统上手动输入简单得多,它可以在脚本自动化输入密码


1 编写脚本4.expect

目的:把远程机器上面的文件同步到本机

内容如下:

#!/usr/bin/expect
set passwd "????"
spawn rsync -av [email protected]:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r" }
"password:" {send "$passwd\r"}
}
expect eof


脚本解释:

spawn rsync -av [email protected]:/tmp/12.txt /tmp/

将远程的/tmp/12.txt 同步到本机/tmp/ 

expect eof

表示脚本结束


2 添加x权限于脚本


[root@centos7-01 sbin]# chmod a+x 4.expect

3 执行脚本

[root@centos7-01 sbin]# ./4.expect 
spawn rsync -av [email protected]:/tmp/12.txt /tmp/
[email protected]'s password: 
receiving incremental file list
12.txt
sent 30 bytes  received 84 bytes  228.00 bytes/sec
total size is 5  speedup is 0.04

4 本机查看

[root@centos7-01 sbin]# ls /tmp/12.txt 
/tmp/12.txt
[root@centos7-01 sbin]# cat !$
cat /tmp/12.txt
1212


expect eof 用法说明:

如果把expect eof 去掉的话,脚本会马上被终止,连传输也没能正常进行。

expect eof 它的作用是可以让命令有缓冲时间进行执行命令.

而interact是停止一个expect的执行 此处用于同步数据文件,所以用expect eof更适合.

取消expect eof参数,添加timeout时间,也是同样没有意义的。



20.32 expect脚本指定host和要同步的文件


1 编写脚本

目的:从本机传输文件到指定host

[root@centos7-01 sbin]# vim 5.expect
#!/usr/bin/expect
set passwd "????."
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

脚本解释:

spawn rsync -av $file root@host:$file

从本机同步文件到对方,file的路径必须是绝对路径

@$host是对方的主机ip地址

$file本机要同步到对方的文件,注意,本机和指定host的目录和文件都将是一样的


2 给予x权限

[root@centos7-01 sbin]# chmod a+x 5.expect

3 执行脚本

[root@centos7-01 sbin]# ./5.expect 192.168.189.129 "/tmp/12.txt"
spawn rsync -av /tmp/12.txt [email protected]:/tmp/12.txt
[email protected]'s password: 
sending incremental file list
12.txt
sent 74 bytes  received 37 bytes  74.00 bytes/sec
total size is 5  speedup is 0.05


20.33 构建文件分发系统 


分发系统介绍

需求背景

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

实现思路

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

核心命令

rsync -av --files-from=list.txt  /  root@host:/

文件分发系统的实现

1 编写脚本rsync.expect

[root@centos7-01 sbin]# vim rsync.expect

#!/usr/bin/expect
set passwd "?????"
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


脚本解释:

set file [lindex $argv 1]

这里的file是一个文件列表文件list.txt

spawn rsync -avR --files-from=$file / root@$host:/

两个"/" 第一个/表示源目录,第二个/比较目标目录

-avR R应用在不确认目标目录是否存在,如果目标目录不存在,会强制创建


2 创建list.txt文件

[root@centos7-01 sbin]# vim /tmp/file.list
/tmp/12.txt
/root/shell/1.sh
/root/111/222/lll.txt


解释说明:

本机需要同步到目标主机的文件

目标机器上必须也要有源机器对应的目录,如果需要强制同步不存在目录的话,需要加上-R(rsync -R)参数


3 创建ip.txt文件

[root@centos7-01 sbin]# vim /tmp/ip.list
192.168.189.129
127.0.0.1


解释:

目标IP地址

保证同步的机器上的密码是一样的

使用密码认证(不安全,容易泄密)

密钥认证


4 创建rsync.sh文件

作用: 遍历ip地址

[root@centos7-01 sbin]# vim /usr/local/sbin/rsync.sh 
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
   ./rsync.expect $ip /tmp/file.list
done


解释:

  ./rsync.expect $ip /tmp/file.list

第一个参数ip地址,

第二个参数文件列表


5 给予脚本x权限

[root@centos7-01 sbin]# chmod a+x rsync.sh 
[root@centos7-01 sbin]# chmod a+x rsync.expect


6 执行shell脚本

[root@centos7-01 sbin]# sh -x rsync.sh 
++ cat /tmp/ip.list
+ for ip in '`cat /tmp/ip.list`'
+ ./rsync.expect 192.168.189.129 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / [email protected]:/
[email protected]'s password: 
building file list ... done
root/
root/111/
root/111/222/
root/111/222/lll.txt
root/shell/
root/shell/1.sh
tmp/

sent 248 bytes  received 65 bytes  626.00 bytes/sec
total size is 5  speedup is 0.02
+ for ip in '`cat /tmp/ip.list`'
+ ./rsync.expect 127.0.0.1 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / [email protected]:/
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:5xydbJFoX0PLowBbp4IHIh+YW/eKvWTHf8JQV2QxTjc.
ECDSA key fingerprint is MD5:e5:22:2e:0c:fd:72:e2:4d:90:43:a6:79:21:10:69:65.
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.
[email protected]'s password: [root@centos7-01 sbin]#


解释说明:

正常输出,

不过127.0.0.1 输出有异常,验证发生问题,但大致思路是没有问题了,不参考座位实验结果。


7 在129检查数据是否被同步

[root@centos7-02 ~]# ls -ll /root/111/222/lll.txt 
-rw-r--r-- 1 root root 0 6月   7 16:20 /root/111/222/lll.txt

总结:

1 根据ip列表(多台需要同步数据的主机)实现多台目标主机传输

2 根据file列表(多个需要同步的文件)实现多文件多台目标主机传输

核心脚本:

rsync.expect 实现远程传输

rsync.sh     实现循环功能

关键文件,两个list文件:

/tmp/ip.list      主机列表

/tmp/file.list    文件列表



20.34 批量远程执行命令


1 创建批量执行命令的脚本exe.expect


#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "?????"
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"

脚本解释:

spawn ssh root@$host

远程登录

expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}

密码验证部分

expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"

执行命令部分


2 创建exe.sh脚本

[root@centos7-01 sbin]# vim exe.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
 ./exe.expect $ip "hostname"
done

脚本解释:

for ip in `cat /tmp/ip.list`

$ip参考/tmp/ip.list里面的信息


3 给予x权限

[root@centos7-01 sbin]# chmod a+x exe*
[root@centos7-01 sbin]# ls -ll exe*
-rwxr-xr-x 1 root root 234 6月   7 17:33 exe.expect
-rwxr-xr-x 1 root root  78 6月   7 17:39 exe.sh


4 执行脚本

[root@centos7-01 sbin]# sh exe.sh 
spawn ssh [email protected]
[email protected]'s password: 
Last login: Thu Jun  7 15:28:28 2018 from 192.168.189.1
[root@centos7-02 ~]# hostname
centos7-02
[root@centos7-02 ~]# spawn ssh [email protected]
[email protected]'s password: 
Last failed login: Thu Jun  7 17:07:57 CST 2018 from 127.0.0.1 on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Thu Jun  7 10:49:48 2018 from 192.168.189.1
[root@centos7-01 ~]# hostname
centos7-01

执行正常,输出正常 


shell结束总结:

  • shell 比较重要,比较难的一个知识点,需要长期积累经验,多练习。

  • 每天练习1-3道shell题


扩展:

shell多线程 http://blog.lishiming.net/?p=448