EXPECT 语法.docx
《EXPECT 语法.docx》由会员分享,可在线阅读,更多相关《EXPECT 语法.docx(15页珍藏版)》请在冰豆网上搜索。
![EXPECT 语法.docx](https://file1.bdocx.com/fileroot1/2022-11/15/10581ad2-01a3-40ab-8cc3-3f733f9960e5/10581ad2-01a3-40ab-8cc3-3f733f9960e51.gif)
EXPECT语法
Expect语法
接触Expect是迫不得已。
系统管理员在工作中经常会遇到这样的问题,需要实现一个自动交互的工具,这个工具可以自动Telnet或者Ftp到指定的服务器上,成功login之后自动执行一些命令来完成所需的工作。
当然,有很多编程语言可以去解决此类问题,比如用C、Perl、或者Expect。
显然,尽管C是无所不能的,但是解决此类问题还是比较困难,除非你熟悉Telnet或者Ftp协议。
曾经见过别人用C实现了一个简单的Telnet客户端协议的程序,可以在这个程序加入自己的代码来捕获服务端的输出,根据这些输出来发送适当的指令来进行远程控制。
使用Perl一样可以实现这样的功能,然而,Expect做的更出色,而且除支持Unix/Linux平台外,它还支持Windows平台,它就是为系统管理和软件测试方面的自动交互类需求而产生的:
Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。
Expect的作者DonLibes在1990年开始编写Expect时对Expect做有如下定义:
Expect是一个用来实现自动交互功能的软件套件(Expect[isa]softwaresuiteforautomatinginteractivetools)。
Expect语言是基于Tcl的,作为一种脚本语言,Tcl具有简单的语法:
cmdargargarg
一条Tcl命令由空格分割的单词组成.其中,第一个单词是命令名称,其余的是命令参数.
$foo
$符号代表变量的值.在本例中,变量名称是foo.
[cmdarg]
方括号执行了一个嵌套命令.例如,如果你想传递一个命令的结果作为另外一个命令的参数,那么你使用这个符号.
"somestuff"
双引号把词组标记为命令的一个参数."$"符号和方括号在双引号内仍被解释.
{somestuff}
大括号也把词组标记为命令的一个参数.但是,其他符号在大括号内不被解释.
反斜线符号()是用来引用特殊符号.例如:
n代表换行.反斜线符号也被用来关闭"$"符号,引号,方括号和大括号的特殊含义.
最好的学习方法就是边干边学,对于已经熟悉一种编程语言的人来说,用另一种新的语言来写程序解决问题,是很容易的事。
所以大概了解一下基本语法后,就一边动手解决问题,一边查手册吧。
关于Tcl和Expect的语法,请参考Unix/Linux平台任务的自动化相关部分。
例1:
下面是一个telnet到指定的远程机器上自动执行命令的Expect脚本,该脚本运行时的输出如下:
#/usr/bin/expectsample_login.exproot111111
spawntelnet10.13.32.307001
Trying10.13.32.30...
Connectedto10.13.32.30.
Escapecharacteris'^]'.
acchoconsolelogin:
root
Password:
Lastlogin:
SatNov1317:
01:
37onconsole
SunMicrosystemsInc. SunOS5.9 May2004
#
LoginSuccessfully...
#uname-p
sparc
#ifconfig-a
lo0:
flags=2001000849mtu8232index1
inet127.0.0.1netmaskff000000
eri0:
flags=1000843mtu1500index2
inet10.13.22.23netmaskffffff00broadcast10.13.22.255
ether0:
3:
ba:
4e:
4a:
aa
#exit
acchoconsolelogin:
Finished...
下面是该脚本的源代码:
#visample_login.exp:
procdo_console_login{loginpass}{
settimeout5
setdone1
settimeout_case0
while($done){
expect{
"consolelogin:
"{send"$loginn"}
"Password:
"{send"$passn"}
"#"{
setdone0
send_user"nnLoginSuccessfully...nn"
}
timeout{
switch--$timeout_case{
0{send"n"}
1{
send_user"Sendareturn...n"
send"n"
}
2{
putsstderr"Logintimeout...n"
exit1
}
}
incrtimeout_case
}
}
}
}
procdo_exec_cmd{}{
settimeout5
send"n"
expect"#"
send"uname-pn"
expect"#"
send"ifconfig-an"
expect"#"
send"exitn"
expect"login:
"
send_user"nnFinished...nn"
}
if{$argc<2}{
putsstderr"Usage:
$argv0loginpasswaord.n"
exit1
}
setLOGIN [lindex$argv0]
setPASS [lindex$argv1]
spawntelnet10.13.32.30 7001
do_console_login$LOGIN$PASS
do_exec_cmd
close
exit0
上面的脚本只是一个示例,实际工作中,只需要重新实现do_exec_cmd函数就可以解决类似问题了。
在例1中,还可以学习到以下Tcl的语法:
1.命令行参数
$argc,$argv0,$argv1...$argvn
if{$argc<2}{
putsstderr"Usage:
$argv0loginpasswaord.n"
exit1
}
2.输入输出
putsstderr"Usage:
$argv0loginpasswaord.n"
3.嵌套命令
setLOGIN [lindex$argv0]
setPASS [lindex$argv1]
4.命令调用
spawntelnet10.13.32.30 7001
5.函数定义和调用
procdo_console_login{loginpass}{
..............
}
6.变量赋值
setdone1
7.循环
while($done){
................
}
8.条件分支Switch
switch--$timeout_case{
0{
...............
}
1{