使用expect实现批量操作的自动化

时间:2022-05-22 16:37:50
Expect 是由 Don Libes 基于 Tcl 语言开发的,并被广泛应用于交互式操作和自动化测试的场景之中,它尤其适用于需要对多台服务器执行相同操作的环境中,可以大幅度得提高系统管理人员的工作效率。目前,大部分 Unix/Linux 系统安装有 expect. 万一系统中没有,可以从 http://expect.nist.gov/ 下载相应的包安装。

Expect 作为基于 Tcl 的高级语言,增加了一些特殊的语法。传统意义上的 Expect 是以 Tcl 扩展包的形式出现的,任何 Tcl 语言编写的应用程序都可以加载 Expect 功能;此外,Expect 已经以模块的方式移植到了 Perl 和 Python 语言中,因此用户同样可以在 Perl 和 Python 脚本中利用 Expect 强大的交互功能。

Send,expect 和 spwan 是 Expect 语言最基本的命令。其中,send 命令会发送字符串给指定进程(process); expect 命令会等待接受该进程返回的结果并且会根据返回的字符串来决定下一步的操作;而 spwan 命令可以发起一个进程的运行。


下面是使用expect进行批量自动化的相关操作的具体例子

1,从配置文件读入密码,并调用expect命令
[root@dtydb0 scripts]# cat expect.sh
#!/bin/bash
for i in `awk '{print $1}' passwd.txt`
do
j=`awk -v I="$i" '{if(I==$1)print $2}' passwd.txt`
k=`awk -v I="$i" '{if(I==$1)print $3}' passwd.txt`
expect login.exp $i $j $k
done

2,密码文件,可以多台主机
cat  passwd.txt
10.4.12.1    root    root
10.4.12.2    root    root

3, 实际工作的exp文件

3.1 用来ssh登录运行相关命令

cat login.exp

[root@dtydb0 scripts]# cat login.exp
#!/usr/bin/expect -f
set ipaddress [lindex $argv 0]
set username [lindex $argv 1]
set passwd [lindex $argv 2]
if { $argc != 3 } {
puts stderr $passwd
puts stderr $username
exit 1
}
set timeout 30
#使用spawn命令来激活ssh程序,模拟终端的输出将能够被expect所读取,模拟终端也能从send输入到远程主机
spawn ssh $username@$ipaddress
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r" }
}
#expect语句等待远程主机的字符串匹配,当匹配到了“yes/no”则执行后面的操作.expect搜索模式"*password:",其中*允许匹配
#任意输入,所以对于避免指定所有细节而言是非常有效的。如果远程主机没有action,所以expect检测到该模式后就继续运行。 一旦接
#收到提示后,下一行就就把密码送给当前进程。
expect "]*"
send "date \r"
send "sh test.sh\r"
send "exit\r "
send "exit\r "
expect eof {exit 1}



3.2  scp 复制文件的例子

#!/usr/bin/expect -f
set ipaddress [lindex $argv 0]
set username [lindex $argv 1]
set passwd [lindex $argv 2]
if { $argc != 3 } {
puts stderr $passwd
puts stderr $username
exit 1
}
set timeout 30
spawn spawn scp -r /home/oracle/dba/scripts/ $username@$ipaddress:/home/oracle/dba/scripts
expect {
"yes/no" { send "yes\r";exp_continue }
"$username@$ipaddress's password:" { send "$passwd\r" }
}
send "exit/r"
expect eof


3.3 批量sqlplus操作例子
--oracle sqlplus
[oracle@dtydb0 dailycheck]$ cat romote_daily_sqlplus.exp
#!/usr/bin/expect -f
set tnsname [lindex $argv 0]
set username [lindex $argv 1]
set passwd [lindex $argv 2]
set timeout 30
spawn sqlplus $username/$passwd@$tnsname
expect "SQL>"
send "select * from dual;\r"
expect "SQL>"
puts "--------talbe spaces ----------"
send "@/home/oracle/dba/scripts/showtbs.sql;\r"
expect "SQL>"
puts "--------top sql ----------"
send "@/home/oracle/dba/scripts/ash_topsql.sql;\r"
expect "SQL>"
send "exit\r"
expect eof



参考资料
http://www.ibm.com/developerworks/cn/aix/library/0909_jinjh_unixlogin/