expect批量同步或执行命令工具

expect脚本同步文件

我们知道主机间传输一个文件受网络、文件大小和磁盘读写速率的影响,在传输一个文件时不可能一下子马上传输到对方,但是使用expect脚本的过程中,值得注意的是在脚本结尾以expect eof结束整个脚本,它的作用是当脚本内涉及到有文件传输时,会让文件传输完成后再彻底结束掉脚本进程,这样会让文件能够成功传输到对方主机上。expect若使用exit或者没有eof这个选项,那么在执行脚本时,expect不管你是否有文件正在传输,当脚本内容执行完成后直接结束掉自己的进程,这样就会造成文件传输失败
用法直接在脚本末尾加上expect eof配置就行了
脚本执行过程
首先创建一个测试文件,查看是否能够同步

[root@localhost src]# touch /tmp/1234566.txt
[root@localhost src]# chmod a+x 4.expect 
[root@localhost src]# cat 4.expect 
#!/usr/bin/expect
set passwd "pwd@123"
spawn rsync -av [email protected]:/tmp/1234566.txt /mnt/
expect {
 "yes/no" { send "yes\r"}
 "password:" { send "$passwd\r" }
 }
expect eof

执行该脚本文件

[root@localhost src]# ./4.expect 
spawn rsync -av [email protected]:/tmp/1234566.txt /mnt/
[email protected]'s password: 
receiving incremental file list
1234566.txt
sent 30 bytes  received 80 bytes  73.33 bytes/sec
total size is 0  speedup is 0.00

这里使用的是本机同步,测试不会影响实际使用效果,只需要将传输来源目标或者本地路径改为自己的即可
查看是否同步到自己主机的/mnt/目录下

[root@localhost src]# cd /mnt/
[root@localhost mnt]# ls
1234566.txt

使用expect编写分发脚本

实现批量分发系统要将同步目录和主机ip两个信息写在指定的保存文件中,这样就会在同步分发时循环这些信息来对这些主机批量同步多个目录
创建目录记录文件和主机ip文件,我这里所有脚本均在/usr/loca/src/目录下,所有在脚本中也会指定这个路径,若在修改自己脚本时,请注意这些自定义路径
文件中的信息可以是多条,一行即是一条记录,这样可以实现循环遍历

[root@localhost src]# cat file.txt 
/mnt/
/tmp/123/
[root@localhost src]# cat ip.txt 
192.168.1.234
192.168.1.235
192.168.1.336

创建expect的脚本文件,脚本内容中把主机ip和同步的目录均做了参数引用,在稍后的sh脚本中会指定引用参数,并对这些参数进行循环操作
rsync指定的--files-from是明确指定同步的目录或文件来源,在expect中则是指定一个参数引用,expect在根据这个参数引用去想用户请求输入这个信息(在这个脚本中这个信息是由sh脚本读取file.txt这个文件来提供给expect的)

[root@localhost src]# vim rsync.expect 
#!/usr/bin/expect
set passwd "pwd@123"
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

shell脚本内容
对目录文件读取,读取后的信息交给expect,让expect使用rsync去同步这些目录。shell中的ip.txt记录的则是一些主机ip,保存在这里的主机ip都会被循环读取并执行指定的expect脚本来同步目录,从而实现了批量的主机目录同步

[root@localhost src]# vim rsync.sh 
#!/bin/bash
for file in `cat /usr/local/src/ip.txt`
  do 
    ./rsync.expect $file /usr/local/src/file.txt
  done

将expect和shell循环脚本都给予可执行权限,并查看脚本的执行过程,这里我的expect和shell脚本都是前缀同名的文件,给予权限时可以使用<br/>*号通配表示。我这里只是同步了一个主机的目录,测试结果不影响实际当中的使用。注意expect脚本后需要eof参数给传输留下执行实际,否则会造成传输失败

[root@localhost src]# chmod a+x rsync.*
[root@localhost src]# sh -x rsync.sh 
++ cat /usr/local/src/ip.txt
+ for file in '`cat /usr/local/src/ip.txt`'
+ ./rsync.expect 192.168.1.234 /usr/local/src/file.txt
spawn rsync -avR --files-from=/usr/local/src/file.txt / [email protected]:/
[email protected]'s password: 
building file list ... done
sent 54 bytes received 12 bytes 132.00 bytes/sec
total size is 0 speedup is 0.00

expect批量执行命令

和上节逻辑类似,根据ip文件中提供的主机,使用for循环遍历出主机,并在for循环内调用expect脚本来登录循环遍历的服务器并逐一执行相应的命令。for每循环一次都会遍历出一个主机ip并使用expect脚本登录并执行命令
for脚本如下,注意for循环里调用的expect可执行脚本的文件名并指定登录主机和执行命令调用的参数

[root@localhost ~]# [root@localhost shell]# cat ins.sh 
#!/bin/bash

for ip in `cat ip.txt`
    do
        echo $ip
        ./inst.expect $ip "hostname;df -h"
done

expect脚本如下,将主机和执行命令分别以调用参数的形式引用,使用命令行输入匹配特定字符来调用执行参数(argv参数对应expect的指定字符匹配)

[root@localhost shell]# cat inst.expect 
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "pwd@123"
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"

另外将主机ip写在一个文件当中,以供for循环遍历来调用

[root@localhost shell]# cat ip.txt 
192.168.1.234

执行结果如,打印出ip.txt文件中主机的hostname和磁盘分区使用情况信息

[root@localhost shell]# sh ins.sh 
192.168.1.234
spawn ssh [email protected]
[email protected]'s password: 
Last login: Thu Sep 27 14:06:21 2018 from 192.168.1.234
[root@localhost ~]# hostname;df -h
localhost.localdomain
Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/cl-root   18G  9.3G  8.6G  52% /
devtmpfs             902M     0  902M   0% /dev
tmpfs                912M     0  912M   0% /dev/shm
tmpfs                912M  8.7M  904M   1% /run
tmpfs                912M     0  912M   0% /sys/fs/cgroup
/dev/sda1            197M  117M   81M  60% /boot
tmpfs                183M     0  183M   0% /run/user/0

猜你喜欢

转载自blog.51cto.com/8844414/2286598