在与服务器登录执行任务的时候,需要执行某项任务,这是最正常不过了;如何有效自动的执行呢?这里介绍自动交互脚本expect的使用。
expect是一个简单的工具语言,如要工作就是进行自动化的人机交互。它的作者对Expect的定义:是一个实现自动交互功能的软件套件(a software suite for automating interactive tools),使用expect,它能帮助我们在合适的情景下进行合适的交互。
expect的核心是spawn、 expect、 send、 set
spawn ## 调用要执行的命令
expect ##等待命令提示信息的出现,也就是捕捉用户输入的提示
send ##发送需要交互的值,替代了用户手动输入内容
set ##设置变量值
interact ##执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。
expect eof # 这个一定要加,与spawn对应表示捕获终端输出信息终止,类似于if....endif
expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof表示脚本执行完成。
1、expect的安装,yum 安装可以帮助解决依赖,如果源码安装需要安装
yum -y expect
2、案例说明
2.1、自动登录系统并执行任务
#!/usr/bin/expect
set host "192.168.16.69"
set passwd "fgjh123." ##设置变量
spawn ssh root@$host ##调用执行命令
expect { ##等待命令出现
"yes/no" {send "yes\r"; exp_continue} ##发送交互值,yes
"password:" {send "$passwd\r"} ##输入密码
}
expect "]*" ##获取当前的终端的命令行提示符
send "uptime\r" ##执行uptime 命令,\r是换行
expect "]*"
send "exit\r" ##执行完命令后,退出当前终端。
expect eof
脚本的执行过程:
# ./login.expect
spawn ssh root@192.168.16.69
root@192.168.16.69's password:
Last login: Fri Dec 4 21:30:27 2014 from 192.168.16.170
# uptime
21:31:19 up 1:14, 1 user, load average: 0.32, 0.18, 0.17
# exit
登出
Connection to 192.168.16.69 closed.
可以看到整个脚本的执行过程,另外需要说明的是,这个shell 脚本一样需要增加执行权限(x)
2.2、使用传递参数
#!/usr/bin/expect
set user [lindex $argv 0] #参数1,用户名
set passwd [lindex $argv 1] #参数2,用户密码
set host [lindex $argv 2] #参数3,远程主机ip或者主机名
set cmd [lindex $argv 3] #参数4,执行命令
spawn ssh $user@$host
expect {
"yes/no" {send "yes\r"; exp_continue}
"password:" {send "$passwd\r"}
}
expect "]*"
send "$cmd\r"
expect "]*"
send "exit\r"
expect eof
脚本的执行是在脚本后面依次写对应的参数,用户名、用户密码、主机ip、执行命令,参数之间使用空格隔开
执行如下:
# ./login.expect root 123123. 192.168.16.69 uptime
spawn ssh root@192.168.16.69
root@192.168.16.69's password:
Last login: Fri Dec 4 21:31:19 2015 from 192.168.16.170
# uptime
21:41:22 up 1:24, 1 user, load average: 0.15, 0.09, 0.13
# exit
登出
Connection to 192.168.16.69 closed.
以上的简单了解了expect的使用,还可以结合shell命令一起使用,构建一个简单的文件分发系统。
3、简单的文件分发系统
对大批量的主机同步文件,首先需要有一台模版的机器,把需要分发的文件都准备好,然后用expect脚本批量同步到目标的远程主机;核心的命令:rsync –av –file-from=list.txt / root@host:/ 。这是使用rysnc的
首先会建立ip.list这是主机的ip ;list.txt是要同步的文件的路径;rsync.expect是自动同步的脚本;rsync.sh是用来获取多台主机的ip和同步的目录的路径登录。
脚本如下:
执行的主机:
[root@balichOS rsycn.expect]# vim ip.list
192.168.17.14
192.168.17.11
~
同步的文件路径
[root@balichOS rsycn.expect]# vim list.txt
/tmp/rsync
/tmp/rsync001
~
同步脚本:
vim rsync.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set user "root"
set passwd "fgjh123."
set file [lindex $argv 1]
spawn rsync -av --file-from=$file / $user@$host:/
expect {
"yes/no" {send "yes\r"}
"password" {send "$passwd\r"}
}
expect eof
vim rsync.sh
#!/bin/bash
for ip in `cat ip.list`
do
echo $ip
[ -x rsync.expect ] || chmod a+x rsync.expect
./rsync.expect $ip list.txt
done
~
然后执行rsync.sh脚本就可以 。
4、批量执行程序
需要做多台机器上执行程序,也可以使用如上的方法
# vim exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set user "root"
set passwd "fgjh123."
set cmd [lindex $argv 1]
spawn ssh $user@$host
expect {
"yes/no" {send "yes\r"}
"password" {send "$passwd\r"}
}
expect "]*"
send "$cmd\r"
expect "]*"
send "exit\r"
expect eof
编写要用于循环ip的exe.sh
[root@balichOS rsycn.expect]# vim exe.sh
#!/bin/bash
for ip in `cat ip.list`
do
echo $ip
[ -x exe.expect ] || chmod a+x exe.expect
./exe.expect $ip 'free -m;uptime'
done
思路都是通过循环ip来实现。
以上都是介绍一种思想,具体的应用需要结合实际情况。
本文转自 巴利奇 51CTO博客,原文链接:http://blog.51cto.com/balich/1720804