Expect 学习笔记.doc
《Expect 学习笔记.doc》由会员分享,可在线阅读,更多相关《Expect 学习笔记.doc(23页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Expect学习笔记Tim一、Expect介绍Expect是一种TCL扩展性的语言,主要用于完成系统交互方面的功能,比如SSH、FTP等,这些程序都需要手工与它们进行互动,而使用Expect就可以模拟人手工互动的过程,使用一种自动的方式控制。Expect中,有三个重要的主命令,分别是spawn、expect、exp_send,这三个命令几乎存在于所有Expect脚本中,除了这些之外,还有很多Expect所特有的参数、变量,它们也作用与Expect的方方面面。二、 Expect命令Expect中命令是最重要的部分,它们完成Expect中最关键的功能,命令使用的特点就是他们本身就可以单独执行,使用
2、上类似于:命令 选项 参数 spawnspawn命令是Expect的初始命令,它用于启动一个进程,之后所有expect操作都在这个进程中进行,如果没有spawn语句,整个expect就无法再进行下去了,使用方法就像下面这样:spawn ssh root192.168.0.1在spawn命令后面,直接加上要启动的进程等信息当然,如果真的不要spawn过程也没有关系,虽然这样就没有办法单独执行,但是这个脚本可以与任何调用它的进程进行交互。除此之外,spawn还支持其他选项:-open启动文件进程,具体说明请参照下面的选项部分。-ignore忽略某些信号,具体说明请参照下面的选项部分。 expect
3、使用方法:expect 表达式 动作 表达式 动作 expect命令用于等候一个相匹配的输出,一旦匹配就执行后面的动作,这个命令接受几个特有参数,用的最多的就是-re,表示使用正则表达式的方式匹配,使用起来就像这样:spawn ssh root192.168.0.1expect “password:” exp_send “wordr”从上面的例子可以看出,expect是依附与spawn命令的,当执行ssh命令后,expect就匹配命令执行后的关键字:password:,如果匹配到关键字就会执行后面包含在括号中的exp_send动作,匹配以及动作可以放在二行,这样就不需要使用括号了,就像下面这样
4、,实际完成的功能与上面是一样的:spawn ssh root192.168.0.1expect “password:”exp_send “wordr”expect命令还有一种用法,它可以在一个expect匹配中同时匹配多个关键字,只需要将关键字放在一个大括号中就可以了:spawn ssh root192.168.0.1expect -re “password:” exp_send “wordr”-re “TopsecOS#” 上面的例子中,在一个expect匹配中可以匹配二个不同情况,如果发现有password:字符就执行后面的动作,而发现的是另外一个TopsecOS#时,因为后面的动作为空,
5、就会退出这个expect动作,在这些动作中也有很多参数,我们在后面来慢慢介绍。上面我们看到了一种【表达式-动作】模式,还有人喜欢使用另一种格式,就像下面这样:spawn ssh root192.168.0.1expect re “password:” exp_send “wordr” re “TopsecOS#” 这种格式的好处是减少了一次缩进,不过看起来就没有那么清晰了,喜欢哪一种可以自己决定。 expect_before在这个语句以下的所有expect语句之前,首先做一次匹配,使用这个命令需要小心,首先来看例子:expect eofeofproc“login:”send “$userr”e
6、xpect eofeofproc“password”send “$passwordr”expect eofeofproc“$prompt”send “$cmdr”上面的例子中,每一个expect都有一个eof过程,而且都是首先检查有没有eof事件,然后再往下检查其他的事件。对于这种情况,我们可以用下面的语句来代替:expect_before eof eofprocexpect “login:”send “$userr”expect “password”send “$passwordr”expect “$prompt”send “$cmdr” expect_after与上面的expect_bef
7、ore一样,不过expect_after是用于在expect语句后面做匹配的,比如下面的语句:expect “login:”send “$userr”eofeofprocexpect “password”send “$passwordr”eofeofprocexpect “$prompt”send “$cmdr”eofeofproc就可以用这样的语句来代替:expect_after eof eofprocexpect “login:”send “$userr”expect “password”send “$passwordr”expect “$prompt”send “$cmdr”看起来简单,
8、但是还有一些需要注意的地方:1. expect_after或者前面说的expect_before语句,都是对这个命令下面的expect语句产生影响的,比如上面的命令中如果把expect_after放在最后一条,那么中间的login之类的expect都是无效的2. expect_after是在expect命令之后做匹配,所以如果有一个expect eof这样的命令,则expect_after eof是无效的,因为先匹配了expect命令中的eof,比如下面的语句:expect_after eof puts “its after”expect eof puts “its expect”则只能匹配到
9、expect中的那个eof,输出是its expect,为什么呢?因为上面的语句代表这样的意思:expect eofputs “its expect”eofputs “its after”这样应该很明显了。3. 如果有多个expect_after或者expect_before命令,则第二个命令会替换第一个,比如下面的情况:expect_after “pat1”act1expect p1expect p2expect_after “pat2” act2 “pat3” act3expect p3这种情况下,程序流程首先匹配 p1 pat1 p2 pat1,然后因为第二个expect_after语句
10、的关系,下面的匹配则是p3 pat2 pat3,这里第二个after语句替换了第一个,p3不再匹配pat1了。4. expect_userexpect_user命令用来匹配从用户那里的输入,之前进行匹配时,都是使用expect命令来匹配程序的输出,但这个命令则可以根据用户的输入进行匹配并完成相应的动作,看看下面的语句:expect_user -re hello puts stdout HELLO; exp_continue这个代码段首先从用户那里获取输入,如果发现输入的是hello字符时,就会激活下面的动作,打印HELLO字符,因为exp_continue命令的存在,这个程序会一直循环下去。
11、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这个命令一般用在动作
12、中,它被使用的条件比较苛刻,看看下面的例子:spawn ssh root192.168.0.1expect -timeout 60-re “password:” exp_send “wordr”; exp_continue-re “TopsecOS#” timeout puts “Expect was timeout”; return在这个例子中,可以发现exp_continue命令的使用方法,首先它要处于一个expect命令中,然后它属于一种动作命令,完成的工作就是从头开始遍历,也就是说如果没有这个命令,匹配第一个关键字以后就会继续匹配第二个关键字,但有了这个命令后,匹配第一个关键字以后,第
13、二次匹配仍然从第一个关键字开始。 exp_internal这是一条用来打开Expect调试模式的命令,它可以将整个匹配,操作过程中间发生的事情显示出来,它接受的值包括:非0值(打开调试模式)、0(关闭调试模式)、-f file(将调试内容写入文件),使用起来就像下面这样:spawn ftp 10.11.105.15exp_internal 1expect -re Name exp_send ftpr; exp_continue -re Pass exp_send ftpr; exp_continue -re ftp exp_send byrexpect EOF注意上面的exp_internal
14、是放在spawn命令后面的。如果想将调试信息放入文件,则修改exp_internal 1语句,变成下面的样子:exp_internal -f output.txt 1具体的组合如下:exp_internal0关闭诊断模式。exp_internal1开启诊断模式,诊断信息输出到标准输出中。exp_internal f file 0开启诊断模式,诊断信息放入文件但不输出到标准输出。exp_internal f file 1开启诊断模式,诊断信息不光写入文件,也输出到标准输出。 exp_pidexp_pid命令用来获取当前spawn的进程号,他支持-i选项,用来指定具体的spawn进程,使用方法就像
15、像下面这样:set pid exp_pid i $spawn_id send_usersend_user命令用来把后面的参数输出到标准输出中去,默认的send、exp_send命令都是将参数输出到程序中去的,用起来就像这样:send_user “Please input passwd:”这个语句就可以在标准输出中打印Please input passwd:字符了。 send_errorsend_error命令用来把后面的参数输出到标准错误输出中去,相比send_user来说它们的最终去向不同。 send_logsend_log命令用来把后面的内容输出到log记录文件中去,这个命令需要与log_
16、file命令配合使用,如果log_file命令指定了一个文件记录程序输出,那么send_log命令则可以自己在文件中添加一些内容。如果没有log_file,那么send_log是无效的,里面的内容不会被打印到标准输出中去。 closeclose命令用来关闭连接,它支持-i选项,用来关闭指定句柄的过程,如果不带任何选项,则关闭当前$spawn_id变量指定的过程。 waitwait命令与close命令相似,都是用来关闭连接的,但wait命令是等待系统主动返回eof,也就是结束信号后才关闭,而不是像close那样无条件关闭,与close命令一样,它也支持-i选项。 log_userlog_user
17、命令用来指定Expect输出的位置,默认情况下log_user的值是1,表示所有输出都放在标准输出中(一般是显示器,如果采用重定向也可以定位到文件中),如果将这个值赋值为0就表示不需要任何输出。 log_filelog_file命令用来将输出记录到一个文件中去,使用格式如下:log_file 文件名选项包括下面几种:-open当一个文件已经被打开时,使用这个选项可以往这个文件里继续添加内容,这个选项一般用于windows系统,因为windows系统中文件是独占的,Linux系统中就不存在这个问题了。-leaveopen当文件已经被打开时,不继续向这个文件中添加内容。-noappend如果文件已
18、存在,那么清空文件中的内容,然后再写入。-a如果文件已存在,则将新内容附加到当前文件的末尾。当这个命令带有文件名时,表示将spawn程序的标准输出记录到文件中,只使用log_file命令但不带文件名则表示关闭记录,这样你就可以只记录自己感兴趣的部分了。 remove_nullsexpect中,默认会去掉返回中的控制符,注意:不要将控制符与空白符搞混,控制符主要是信号,他们是不会显示在屏幕上的,比如使用ctrl+c(中断)、ctrl+d(终止)等组合键发送的信号,信号是ASCII码表中01-31区间中的字符;空白符则是可以显示出来的空白符号,比如空格、回车、换行、制表等一系列符号。remove_
19、nulls命令可以控制是否去掉返回中的控制符,使用方法如下:remove_nulls0# 关闭自动去掉控制符的功能remove_nulls1# 开始知道去掉控制符的功能,这是默认值。 match_maxmatch_max用来设置expect_out(buffer)变量的缓存大小,默认情况下expect_out(buffer)变量缓存是2000个字符,你可以设置这个大小来设置更符合实际的缓存,使用方法如下:match_max65535这是一般的方法,它还支持2个选项,其中-d表示设置为默认值,也就是default的意思,-i则表示设置某个spawn_id指定的进程缓存,使用方法如下:match_
20、max-d 1048576match_max-ilo_spawnid使用-d选项一般是用于多个spawn进程同时运行的情况。 trap在脚本运行期间监听系统信号,系统信号支持3种方式:C语言方式,比如SIGINT、SIGHUP等;简略方式,比如-INT、-SIGHUP;Linux系统的kill模式,比如9、15等;监听到这些信号之后就执行规定的动作。使用方法就象这样:trap send_user “bye byer”exit SIGINT上面的脚本中,在脚本运行期间一旦用户发送了SIGINT信号(一般都是ctrl+c),就会打印bye bye字符,然后退出脚本。信号的具体表格请查阅其他资料,而
21、且建议使用C语言方式,因为这是目前使用最广泛的,比较容易做代码移植。如果希望一次性监听多个信号,则可以把信号一次性的赋给trap命令,比如:trap intproc SIGINT SIGHUP SIGQUITtrap支持2个选项:-name number,分别返回监听到的信号名称及数值,使用方法如下:trap send_user “signal name is trap name”send_user “signal integer is trap number”exit SIGINT SIGHUP SIGQUIT如果希望取消某些信号,则有一个特殊关键字SIG_IGN来做这件是,比如:trap
22、SIG_IGN SIGINT SIGHUP SIGQUIT 这样在脚本运行期间即使用户输入这些信号也会被忽略掉。有时候希望在脚本前半部分忽略信号,但后半部分不忽略,使用特殊关键字SIG_DFL可以恢复这些信号的功能:trap SIG_IGN SIGINT SIGHUP SIGQUIT # 取消这些信号功能.trap SIG_DFL SIGINT SIGHUP SIGQUIT # 恢复这些信号功能 exitexit命令功能很简单,就是直接退出脚本,但是你可以利用这个命令对脚本做一些扫尾工作,比如下面这样:exit onexit exec rm $tmpfilesend_user “Good by
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Expect 学习笔记 学习 笔记
限制150内