本文简要介绍了expect工具语言的功能、用法,并以实例来具体说明
expect是什么
Expect是一个免费的编程工具语言,用来完成通信过程中的交互式任务,而无需人的干预。
通过shell虽然可以实现诸如循环、判断等控制流功能,但是在一些需要实现信息交互的场合,还是要通过人工干预来完成。为实现信息的交互,expect被发明,并不断随着时间的推移而功能日益强大。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。
安装expect
首先查看系统中是否有安装expect。
# whereis expect
Expect工具是依赖tcl的,所以也需要安装tcl。
首先下载并安装tcl,这里安装8.4.19版本。
# wget https://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz
# tar zxvf tcl8.4.19-src.tar.gz
# cd tcl8.4.19/unix && ./configure
# make
# make install
然后下载expect并安装。
# wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz
# tar zxvf expect5.45.tar.gz
# cd expect5.45
# ./configure --with-tcl=/usr/local/lib --with-tclinclude=../tcl8.4.19/generic
# make
# make install
# ln -s /usr/local/bin/expect /usr/bin/expect
注意这里的configure命令需要使用–with-tclinclude选项传入tcl安装包中的generic文件夹路径。
安装完成之后运行expect命令,查看是否安装成功。
# expect
expect1.1>
基本操作
Expect脚本中常用的命令包括spawn, expect, send, interact等。
spawn shell-command
后面接的是我们要执行的shell命令,将启动一个子进程
expect “hi”
该命令从进程接受字符串”hi”,如果接受的字符串和期待的字符串不匹配,则一直阻塞,直到匹配上或者等待超时才继续往下执行
{send “hello\r”}
向进程发送字符串,与手动输入内容等效,当匹配到内容''hi"后输出“hello”,“\r”是代表是返回字符。
interact
该命令将控制权交给控制台,之后就可以进行人工操作了。通常用于使用脚本进行自动化登录之后再手动执行某些命令。如果脚本中没有这一条语句,脚本执行完将自动退出。
set timeout 30
设置超时时间timeout为30s,expect命令阻塞超时时会自动往下继续执行。将timeout配置为-1时表示expect一直阻塞直到与期待的字符串匹配上才继续往下执行。超时时间timeout默认为10s。
[lindex $argv n]
可以在脚本中使用该命令获取在脚本执行时传入的第n个参数。这里argv为传入的参数,另外argv为传入的参数,另外argc表示传入参数的个数,$argv0表示脚本名字。
另外我们也可以使用[lrange $argv sn en]命令获取第sn到第en个参数。
实例参考
login.exp :
#!/usr/bin/expect
set ip [lindex $argv 0]
#这条命令是将变量ip的值设置为传入进来的第一个参数。[lindex $argv 0]表示的就是第一个参数的值
set port [lindex $argv 1]
#这条命令是将变量port的值设置为传入进来的第二个参数。[lindex $argv 1]表示的就是第二个参数的值
set passwd ""
spawn ssh $ip -p$port
#使用变量,这里使用的方法跟shell脚本一样
expect {
#匹配输出内容,返回内容,exp_continue表示继续执行下一步 "*password" {send "123456\r"}
"yes/no" {send "yes\r";exp_continue}
"password:" {send "$passwd\r"}
}
interact
#执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行一段命令就退出,可改为[expect eof]
操作如下:
[root@localhost shell]# cat login.exp
[root@localhost shell]# ./login.exp 192.168.2.11 22 #多个参数直接以空格间隔,第一个参数:192.168.2.11 第二个参数22
本文由以下文章整理而来: