Expect 学习笔记Word格式文档下载.docx
- 文档编号:19911050
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:28
- 大小:33.63KB
Expect 学习笔记Word格式文档下载.docx
《Expect 学习笔记Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Expect 学习笔记Word格式文档下载.docx(28页珍藏版)》请在冰豆网上搜索。
,如果匹配到关键字就会执行后面包含在{}括号中的exp_send动作,匹配以及动作可以放在二行,这样就不需要使用{}括号了,就像下面这样,实际完成的功能与上面是一样的:
spawnsshroot@192.168.0.1
”
exp_send“word\r”
expect命令还有一种用法,它可以在一个expect匹配中同时匹配多个关键字,只需要将关键字放在一个大括号中就可以了:
expect{
-re“password:
-re“TopsecOS#”{}
}
上面的例子中,在一个expect匹配中可以匹配二个不同情况,如果发现有password:
字符就执行后面的动作,而发现的是另外一个TopsecOS#时,因为后面的动作为空,就会退出这个expect动作,在这些动作中也有很多参数,我们在后面来慢慢介绍。
上面我们看到了一种【表达式-动作】模式,还有人喜欢使用另一种格式,就像下面这样:
expect–re“password:
”{
exp_send“word\r”
}–re“TopsecOS#”{
这种格式的好处是减少了一次缩进,不过看起来就没有那么清晰了,喜欢哪一种可以自己决定。
expect_before
在这个语句以下的所有expect语句之前,首先做一次匹配,使用这个命令需要小心,首先来看例子:
eofeofproc
“login:
”{send“$user\r”}
expect{
eofeofproc
“password”{send“$password\r”}
“$prompt”{send“$cmd\r”}
上面的例子中,每一个expect都有一个eof过程,而且都是首先检查有没有eof事件,然后再往下检查其他的事件。
对于这种情况,我们可以用下面的语句来代替:
expect_beforeeofeofproc
expect“login:
expect“password”{send“$password\r”}
expect“$prompt”{send“$cmd\r”}
expect_after
与上面的expect_before一样,不过expect_after是用于在expect语句后面做匹配的,比如下面的语句:
eofeofproc
就可以用这样的语句来代替:
expect_aftereofeofproc
看起来简单,但是还有一些需要注意的地方:
1.expect_after或者前面说的expect_before语句,都是对这个命令下面的expect语句产生影响的,比如上面的命令中如果把expect_after放在最后一条,那么中间的login之类的expect都是无效的
2.expect_after是在expect命令之后做匹配,所以如果有一个expecteof这样的命令,则expect_aftereof是无效的,因为先匹配了expect命令中的eof,比如下面的语句:
expect_aftereof{puts“it’safter”}
expecteof{puts“it’sexpect”}
则只能匹配到expect中的那个eof,输出是it’sexpect,为什么呢?
因为上面的语句代表这样的意思:
eof{puts“it’sexpect”}
eof{puts“it’safter”}
这样应该很明显了。
3.如果有多个expect_after或者expect_before命令,则第二个命令会替换第一个,比如下面的情况:
expect_after“pat1”act1
expectp1
expectp2
expect_after“pat2”act2“pat3”act3
expectp3
这种情况下,程序流程首先匹配p1pat1p2pat1,然后因为第二个expect_after语句的关系,下面的匹配则是p3pat2pat3,这里第二个after语句替换了第一个,p3不再匹配pat1了。
4.
expect_user
expect_user命令用来匹配从用户那里的输入,之前进行匹配时,都是使用expect命令来匹配程序的输出,但这个命令则可以根据用户的输入进行匹配并完成相应的动作,看看下面的语句:
expect_user{
-rehello
{putsstdout"
HELLO"
;
exp_continue}
这个代码段首先从用户那里获取输入,如果发现输入的是hello字符时,就会激活下面的动作,打印HELLO字符,因为exp_continue命令的存在,这个程序会一直循环下去。
exp_send
在上面的介绍中,我们已经看到了exp_send命令的使用,exp_send命令是expect中的动作命令,它还有一个完成同样工作的同胞:
send,exp_send命令可以发送一些特殊符号,我们看到了\r(回车),还有一些其他的比如:
\n(换行)、\t(制表符)等等,这些都与TCL中的特殊符号相同。
send命令有几个可用的参数:
-i指定spawn_id,这个参数用来向不同spawn_id的进程发送命令,是进行多程序控制的关键参数。
-ss代表slowly,也就是控制发送的速度,这个参数使用的时候要与expect中的变量send_slow相关联
exp_continue
这个命令一般用在动作中,它被使用的条件比较苛刻,看看下面的例子:
-timeout60
”{exp_send“word\r”;
timeout{puts“Expectwastimeout”;
return}
在这个例子中,可以发现exp_continue命令的使用方法,首先它要处于一个expect命令中,然后它属于一种动作命令,完成的工作就是从头开始遍历,也就是说如果没有这个命令,匹配第一个关键字以后就会继续匹配第二个关键字,但有了这个命令后,匹配第一个关键字以后,第二次匹配仍然从第一个关键字开始。
exp_internal
这是一条用来打开Expect调试模式的命令,它可以将整个匹配,操作过程中间发生的事情显示出来,它接受的值包括:
非0值(打开调试模式)、0(关闭调试模式)、-ffile(将调试内容写入文件),使用起来就像下面这样:
spawnftp10.11.105.15
exp_internal1
-re"
Name"
{exp_send"
ftp\r"
Pass"
ftp>
"
by\r"
expectEOF
注意上面的exp_internal是放在spawn命令后面的。
如果想将调试信息放入文件,则修改exp_internal1语句,变成下面的样子:
exp_internal-foutput.txt1
具体的组合如下:
exp_internal0关闭诊断模式。
exp_internal1开启诊断模式,诊断信息输出到标准输出中。
exp_internal–ffile0开启诊断模式,诊断信息放入文件但不输出到标准输出。
exp_internal–ffile1开启诊断模式,诊断信息不光写入文件,也输出到标准输出。
exp_pid
exp_pid命令用来获取当前spawn的进程号,他支持-i选项,用来指定具体的spawn进程,使用方法就像像下面这样:
setpid[exp_pid–i$spawn_id]
send_user
send_user命令用来把后面的参数输出到标准输出中去,默认的send、exp_send命令都是将参数输出到程序中去的,用起来就像这样:
send_user“Pleaseinputpasswd:
这个语句就可以在标准输出中打印Pleaseinputpasswd:
字符了。
send_error
send_error命令用来把后面的参数输出到标准错误输出中去,相比send_user来说它们的最终去向不同。
send_log
send_log命令用来把后面的内容输出到log记录文件中去,这个命令需要与log_file命令配合使用,如果log_file命令指定了一个文件记录程序输出,那么send_log命令则可以自己在文件中添加一些内容。
如果没有log_file,那么send_log是无效的,里面的内容不会被打印到标准输出中去。
close
close命令用来关闭连接,它支持-i选项,用来关闭指定句柄的过程,如果不带任何选项,则关闭当前$spawn_id变量指定的过程。
wait
wait命令与close命令相似,都是用来关闭连接的,但wait命令是等待系统主动返回eof,也就是结束信号后才关闭,而不是像close那样无条件关闭,与close命令一样,它也支持-i选项。
log_user
log_user命令用来指定Expect输出的位置,默认情况下log_user的值是1,表示所有输出都放在标准输出中(一般是显示器,如果采用重定向也可以定位到文件中),如果将这个值赋值为0就表示不需要任何输出。
log_file
log_file命令用来将输出记录到一个文件中去,使用格式如下:
log_file<
选项>
文件名
选项包括下面几种:
-open当一个文件已经被打开时,使用这个选项可以往这个文件里继续添加内容,这个选项一般用于windows系统,因为windows系统中文件是独占的,Linux系统中就不存在这个问题了。
-leaveopen当文件已经被打开时,不继续向这个文件中添加内容。
-noappend如果文件已存在,那么清空文件中的内容,然后再写入。
-a如果文件已存在,则将新内容附加到当前文件的末尾。
当这个命令带有文件名时,表示将spawn程序的标准输出记录到文件中,只使用log_file命令但不带文件名则表示关闭记录,这样你就可以只记录自己感兴趣的部分了。
remove_nulls
expect中,默认会去掉返回中的控制符,注意:
不要将控制符与空白符搞混,控制符主要是信号,他们是不会显示在屏幕上的,比如使用ctrl+c(中断)、ctrl+d(终止)等组合键发送的信号,信号是ASCII码表中01-31区间中的字符;
空白符则是可以显示出来的空白符号,比如空格、回车、换行、制表等一系列符号。
remove_nulls命令可以控制是否去掉返回中的控制符,使用方法如下:
remove_nulls0#关闭自动去掉控制符的功能
remove_nulls1#开始知道去掉控制符的功能,这是默认值。
match_max
match_max用来设置expect_out(buffer)变量的缓存大小,默认情况下expect_out(buffer)变量缓存是2000个字符,你可以设置这个大小来设置更符合实际的缓存,使用方法如下:
match_max65535
这是一般的方法,它还支持2个选项,其中-d表示设置为默认值,也就是default的意思,-i则表示设置某个spawn_id指定的进程缓存,使用方法如下:
match_max-d1048576
match_max-ilo_spawnid
使用-d选项一般是用于多个spawn进程同时运行的情况。
trap
在脚本运行期间监听系统信号,系统信号支持3种方式:
C语言方式,比如SIGINT、SIGHUP等;
简略方式,比如-INT、-SIGHUP;
Linux系统的kill模式,比如9、15等;
监听到这些信号之后就执行规定的动作。
使用方法就象这样:
trap{
send_user“byebye\r”
exit
}SIGINT
上面的脚本中,在脚本运行期间一旦用户发送了SIGINT信号(一般都是ctrl+c),就会打印byebye字符,然后退出脚本。
信号的具体表格请查阅其他资料,而且建议使用C语言方式,因为这是目前使用最广泛的,比较容易做代码移植。
如果希望一次性监听多个信号,则可以把信号一次性的赋给trap命令,比如:
trapintproc{SIGINTSIGHUPSIGQUIT}
trap支持2个选项:
-name–number,分别返回监听到的信号名称及数值,使用方法如下:
send_user“signalnameis[trap–name]”
send_user“signalintegeris[trap–number]”
}{SIGINTSIGHUPSIGQUIT}
如果希望取消某些信号,则有一个特殊关键字SIG_IGN来做这件是,比如:
trapSIG_IGN{SIGINTSIGHUPSIGQUIT}
这样在脚本运行期间即使用户输入这些信号也会被忽略掉。
有时候希望在脚本前半部分忽略信号,但后半部分不忽略,使用特殊关键字SIG_DFL可以恢复这些信号的功能:
trapSIG_IGN{SIGINTSIGHUPSIGQUIT}#取消这些信号功能
..................
trapSIG_DFL{SIGINTSIGHUPSIGQUIT}#恢复这些信号功能
exit
exit命令功能很简单,就是直接退出脚本,但是你可以利用这个命令对脚本做一些扫尾工作,比如下面这样:
exit–onexit{
execrm$tmpfile
send_user“Goodbye\n”
interact
interact命令是Expect中非常重要的命令之一,它用来在脚本中将控制权交给用户,由用户与spawn生成的进程进行交互,比如登录ftp服务器并下载的过程中,登录ftp服务器的过程可以由用户输入自己的用户名和密码,然后用户再输入q字符将控制权交给脚本,由脚本完成后面的交互动作,这个功能的实现代码如下:
spawnftp172.18.1.111
interact{
"
d"
{puts[execdate]}
q"
{return}
send"
\r"
ftp>
{send"
default{}
上面的代码每一行的含义如下:
第一行的spawn命令用来打开一个ftp登录过程,需要特别注意的是,interact命令是不能单独运行的,他必须在一个spawn过程中才能生效,这一点与expect命令是相同的,interact命令也支持-i参数用来做多进程控制,但目前我们不涉及这部分。
第二行的interact命令使用起来就和expect命令完全一样了,当用户输入d这个字符时,执行date命令,这里只是为了演示一下,没有实际意义,输入q字符就退出interact交互过程,这个退出交互过程是由return命令实现的,这也是要特别注意的,如果没有这个命令,则后续的命令都无法生效了,因为你没有将控制权从用户那里转交回脚本;
除了d、q这2个字符,用户输入的任何其他字符都会被忠实的交给ftp过程,所以用户可以在这里进行ftp用户登录以及其他操作,操作完了按一下q就可以了,真实代码中当然不能用q来做这样的动作,因为如果用户的用户名中如果正好有这个字符可就出问题了,你可以找一个不常用的字符来代替,还需要注意一点:
interact并不是只能监听一个字符,你尽可以用一个字符串来代表交互完成,比如OK或者I’mFinished\r等,像这样的监听字符是不会显示在屏幕上面的。
下面的send\r命令很重要,因为下面的expect命令需要匹配ftp>
字符,但interact过程将权限交给脚本的时候,expect的buffer是空的,必须使用send命令将程序的提示符推到buffer里面去,后面的过程就没什么重要的部分了。
interact命令也支持-gl、-ex、-re选项,而且与expect命令相似,它也有interact_out这个专用数组来做其他操作,数组包括interact_out(X,string),其中X是0-9之间的数字,比如interact_out(0,string)表示所有匹配到的字符等;
但是注意interact_out这个数组中不包含interact_out(buffer)这个变量,它是与expect_out(buffer)这个变量合并的。
想看更具体的内容,请参阅第三部分。
interpreter
interpreter用于在expect过程中调用解释器,执行到这一句之后,expect会暂时停下来显示解释器,可以在解释器中调试脚本中的内容,比如puts内部变量的值或者其他操作,到最后使用return命令就可以让脚本继续向下执行了。
调用解释器之后,可以使用更多的interpreter命令调用多个解释器,最后还是用return返回。
三、Expect选项
-i选项
-i选项一般用于同时控制多个spawn进程,通过这个选项向不同spawn_id发送命令就可以同时控制多个进程了,它有二种使用方法:
1.直接使用:
spawnftpconnect
setspid_ftp$spawn_id
spawntelnetconnect
setspid_telnet$spawn_id
exp_send–i$spid_ftp“ftpcommand”
exp_send–i$spid_telnet“telnetcommand”
2.expect过程调用
-i$spid
-timeout"
yourtimeout"
-re"
.+"
{appendresult$expect_out(buffer)}
otherexitcondition"
{}
-d选项
几乎所有expect命令都支持-d选项,d代表default,也就是设置某些命令的默认值,比如:
remove_nulls–d1
timeout–d30
-f选项
f代表file,某些Expect命令支持这个选项,比如exp_internal命令,这个选项用来将某些命令的输出放入一个文件中去,因此这个选项后面必须带有文件的路径作为值。
-s选项
s代表slowly,也就是发送速度,这个选项一般用于send族命令中,比如send、exp_send、send_user、send_error等等,使用这个选项之前,必须先对send_slow变量赋值,这个变量赋值方法的说明请查看第三部分。
-h选项
h代表human,用来模拟人敲击键盘的动作,可以用于所有send命令族,比如exp_send、send_user等等,使用之前必须先对send_human变量赋值,这个变量的详细说明请查看第三部分。
-gl选项
gl代表global,用于指定全局类型的表达式,用于expect、interact命令族中,比如expect、expect_user、expect_error等,global形式的表达式与DOS的通配符相似,用*表示任意多个任意字符,?
表示一个任意字符,这是一种很简单的表达式。
-ex选项
ex代表exact,用于指定精确类型的表达式,用于expect、interact命令族中,这种类型的表达式特点就是所有字符都精确代表它本身的含义,不存在通配符。
-re选项
re代表regularexpression,也就是正则表达式,用于expect、interact命令族中,这种类型的表达式具有匹配一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Expect 学习笔记 学习 笔记