linux 学习笔记-075-Shell 编程-expect 脚本同步文件,expect 脚本指定 host 和要同步的文件,构建文件分发系统,批量远程执行命令

发布于 2018-04-26  171 次阅读


expect 脚本同步文件

expect 把文件同步到另一台机器上,使用的核心命令是 rsync,这里依然是两台机器,分别是 A 和 B

01:

使用 rsync 把文件同步到 B 机器,加上"expect eof"

[root@am-01:~/expect#] vim 4.expect

#!/usr/bin/expect

set passwd "itsupport.0"

spawn rsync -av root@172.17.1.242:/tmp/12.txt /tmp/

expect {

    "yes/no" { send "yes\r"}

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

}

expect eof

02:

测试加上了"expect eof"的脚本效果,可以见到 A 和 B 均有/tmp/12.txt 文件了,而且脚本运行完成会自动退出远程登录

[root@am-01:~/expect#] chmod a+x 4.expect

[root@am-01:~/expect#] ./4.expect

spawn rsync -av root@172.17.1.242:/tmp/12.txt /tmp/

root@172.17.1.242'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

[root@am-01:~/expect#] ls /tmp/12.txt

/tmp/12.txt
[root@am-02:~#] ls /tmp/12.txt

/tmp/12.txt

03:

删除"expect eof"的脚本效果,可以见到,同步还没完成,就已经退出登录了,最终可得出结论,"expect eof"或者"interact"是不能少的

[root@am-01:~/expect#] ./4.expect

spawn rsync -av root@172.17.1.242:/tmp/12.txt /tmp/

root@172.17.1.242's password:
[root@am-02:~#] ls /tmp/12.txt

ls: 无法访问/tmp/12.txt: 没有那个文件或目录

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

01:

指定超时时间,这里使用"3.expect"这个脚本试验,多了一句"set timeout 5",表示超时时间为 5 秒,假如是-1 的话,则永不超时

[root@am-01:~/expect#] vim 3.expect

#!/usr/bin/expect

set user [lindex $argv 0]

set host [lindex $argv 1]

set passwd "itsupport.0"

set cm [lindex $argv 2]

spawn ssh $user@$host

expect {

    "yes/no" { send "yes\r"}

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

}

expect "]*"

send "$cm\r"

set timeout 5

expect "]*"

send "exit\r"

02:

测试可以见到,超时时间为 5 秒

[root@am-01:~/expect#] ./3.expect root 172.17.1.242 "vmstat 1"

spawn ssh root@172.17.1.242

root@172.17.1.242's password:

Last failed login: Thu Apr 26 18:03:41 CST 2018 from 172.17.1.240 on ssh:notty

There were 2 failed login attempts since the last successful login.

Last login: Thu Apr 26 17:52:01 2018 from 172.17.1.1

[root@am-02:~#] vmstat 1

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  66092  72656      0 306240    0    0     0    21    6   13  0  0 99  0  0

 0  0  66092  72708      0 306292    0    0     0     0   72  107  0  1 100  0  0

 0  0  66092  72708      0 306292    0    0     0     0   66   92  0  0 100  0  0

 0  0  66092  72708      0 306292    0    0     0     0   64   96  0  0 100  0  0

 0  0  66092  72676      0 306292    0    0     0     0   85  115  0  1 100  0  0

[root@am-01:~/expect#]

03:

使用自定义参数的方式,指定 host 和要同步的文件

[root@am-01:~/expect#] vim 5.expect

#!/usr/bin/expect

set passwd "itsupport.0"

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

04:

测试,这里需要注意$file 参数,要写需要同步的文件的绝对路径,这里只能同步一个文件

[root@am-01:~/expect#] chmod a+x 5.expect

[root@am-01:~/expect#] ./5.expect 172.17.1.242 "/tmp/12.txt"

spawn rsync -av /tmp/12.txt root@172.17.1.242:/tmp/12.txt

root@172.17.1.242's password:

sending incremental file list

12.txt



sent 79 bytes  received 31 bytes  73.33 bytes/sec

total size is 5  speedup is 0.05

构建文件分发系统

需求:

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

思路:

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

核心命令:

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

01:

首先写 rsync.expect 脚本,这里用到了"--files-from=$file",这里的$file 是一个参数,因为这次要做的是一次同步多个文件,这里源目录和目标目录都是根目录

[root@am-01:~/expect#] vim rsync.expect

#!/usr/bin/expect

set passwd "itsupport.0"

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

02:

创建文件列表文件,这个文件列表的路径,要保证在对端服务器上也有这个路径,也可以在 rsync 的时候加上-R 创建级联目录

[root@am-01:~/expect#] vim /tmp/list.txt

/tmp/12.txt

/tmp/21.txt

/root/shell/1.sh

03:

创建 IP 列表文件,其中,做这个实验,要保证每台对端服务器的登录密码都一样,要不然设置挨个输入密码,不过也可以设置为密钥验证,那样就不用输入密码了

[root@am-01:~/expect#] vim /tmp/ip.list

172.17.1.242

172.17.1.243

04:

创建 rsync 的 shell 脚本,通过脚本运行"rsync.expect",并从"/tmp/ip.list"和"/tmp/list.txt"读取第一个参数和第二个参数

[root@am-01:~/expect#] vim rsync.sh

#!/bin/bash

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

do

    echo $ip

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

done

05:

测试,可以见到脚本运行正常

[root@am-01:~/expect#] chmod a+x rsync.expect

[root@am-01:~/expect#] sh -x rsync.sh

++ cat /tmp/ip.list

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

+ echo 172.17.1.242

172.17.1.242

+ ./rsync.expect 172.17.1.242 /tmp/list.txt

spawn rsync -av --files-from=/tmp/list.txt / root@172.17.1.242:/

root@172.17.1.242's password:

building file list ... done

tmp/



sent 123 bytes  received 15 bytes  276.00 bytes/sec

total size is 5  speedup is 0.04

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

+ echo 172.17.1.243

172.17.1.243

+ ./rsync.expect 172.17.1.243 /tmp/list.txt

spawn rsync -av --files-from=/tmp/list.txt / root@172.17.1.243:/

root@172.17.1.243's password:

building file list ... done

root/

root/shell/

root/shell/1.sh

tmp/

tmp/12.txt

tmp/21.txt



sent 255 bytes  received 78 bytes  666.00 bytes/sec

total size is 5  speedup is 0.02
[root@am-02:~#] ls -l /root/shell/1.sh

-rw-r--r-- 1 root root 0 4 月  26 23:15 /root/shell/1.sh
[root@am-03:~#] ls -l /root/shell/1.sh

-rw-r--r-- 1 root root 0 4 月  26 23:15 /root/shell/1.sh

批量远程执行命令

有时候除了批量传输文件外,还得批量执行命令来完成一些操作

01:

创建一个"exe.expect"脚本,这里第一个参数是主机名(ip),第二个参数是要执行的命令(cm)

[root@am-01:~/expect#] vim exe.expect

#!/usr/bin/expect

set host [lindex $argv 0]

set passwd "itsupport.0"

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"

02:

创建 shell 脚本"exe.sh"

[root@am-01:~/expect#] vim exe.sh

#!/bin/bash

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

do

    echo $ip

    ./exe.expect $ip "w;free -m;ls /tmp"

done

03:

测试可以见到,脚本运行正常

[root@am-01:~/expect#] sh -x exe.sh

++ cat /tmp/ip.list

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

+ echo 172.17.1.242

172.17.1.242

+ ./exe.expect 172.17.1.242 'w;free -m;ls /tmp'

spawn ssh root@172.17.1.242

root@172.17.1.242's password:

Last login: Thu Apr 26 23:43:53 2018 from 172.17.1.240

[root@am-02:~#] w;free -m;ls /tmp

 23:44:53 up 12 min,  2 users,  load average: 0.00, 0.03, 0.05

USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT

root     pts/0    172.17.1.1       23:36    7:17   0.06s  0.06s -bash

root     pts/1    172.17.1.240     23:44    0.00s  0.07s  0.02s w

              total        used        free      shared  buff/cache   available

Mem:            979         546         266           6         166         285

Swap:          2047           0        2047

12.txt  21.txt  mysql.sock

[root@am-02:~#] + for ip in '`cat /tmp/ip.list`'

+ echo 172.17.1.243

172.17.1.243

+ ./exe.expect 172.17.1.243 'w;free -m;ls /tmp'

spawn ssh root@172.17.1.243

root@172.17.1.243's password:

Last login: Thu Apr 26 23:43:53 2018 from 172.17.1.240

[root@am-03:~#] w;free -m;ls /tmp

 23:44:54 up 12 min,  2 users,  load average: 0.00, 0.04, 0.07

USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT

root     pts/0    172.17.1.1       23:36    7:10   0.07s  0.07s -bash

root     pts/1    172.17.1.240     23:44    0.00s  0.07s  0.01s w

              total        used        free      shared  buff/cache   available

Mem:            979         539         288           6         151         295

Swap:          2047           0        2047

12.txt  21.txt  mysql.sock