expect

来源:互联网 发布:android 知乎源码 编辑:程序博客网 时间:2024/05/20 02:28

例一 基础启用

#!/usr/bin/expectspawn telnet 118.88.32.2expect eof  exit 

第一行是固定的
spawn [spɔn] 是一个关键命令,他是启用一个命令或是程序,这里是动用telnet和后续的动作

例二 基础使用

#!/usr/bin/expectspawn telnet 118.88.32.2expect "sername:" {exp_send "huawei\r"}expect "assword:" {exp_send "q1w2p0\r"}expect eof  exit

这里expect [ɪk’spɛkt] 是根据spawn执行后的信息,做出判断,在执行后续的操作
还有一种写法,省略了{}

#!/usr/bin/expectspawn telnet 118.88.32.203expect "sername:" exp_send "huawei\r"expect "assword:"exp_send "q1w2p0\r"expect eof  exit 

设置永不超时

set timeout -1

例重点,数据的使用

set estr [ list "\<" "\>" "\%" "\&" "\\"]foreach str $estr {    puts $str        incr i}

set 生名一个数据 estr格式如TCL一样
下面是循环,把数据每个值都进行一些操作

例三简单多条件

#!/usr/bin/expectspawn telnet 118.88.32.203expect {-re "sername:" {exp_send "huawei\r"}-re "assword:" {exp_send "q1w2p0o9\r"}}expect eof  exit 

当有好几种情况发生时,就使用-re参数进行判断,此例是情况是这样
如果发生sername 时执行后续命令,如果发现assword时执行后续命令
注意,只循环一次。如果都没有执行的就等待,常见使用方式 如果有的设备需要帐号,有的设备不需要帐号。

for的用法

for {set i 10} {$i < $argc} {incr i} {expect {-re "<.*>|\[.*\]" {send "disp int [lindex $argv $i] \| in Last 300\n"}}send "#doopt#\n"}send "#displast300end#\n"}

读文件,每行进行显示

#!/usr/bin/expect#set server_p [lindex $argv 0]set file [open /opt/lampp/htdocs/dashboard/ipmancil/devconfig/basesw/20171203/telssh.txt]set n 0set fd [open /opt/lampp/htdocs/dashboard/ipmancil/devconfig/basesw/20171203/telssh.txt r]while {[gets $fd line] != -1} {    incr n#   puts "$n + $line"    spawn nc -v -z -w 2 $line 22-23}#spawn -open $file#expect nameserver {puts "it' s name server address"}exit

大神用法

结果alloc 0/max 262144, alloc failed 0将保存在expect_out(buffer)中set b ""regexp {.*(\d+)/max.*} $expect_out(buffer) match $b b 就是你要的数值

expect中使用exec执行shell命令的方法
google了一下,有些文章说需要对shell命令进行修改替换,但我试了一下,依然报错。

继续google,终于发现了一个很简单的解决方法,命令如下:

exec sh -c {your commands here}。

获取ip的脚本可以写成:

set idcid [exec sh -c {ifconfig eth0 | grep Mask | cut -d: -f2 | awk ‘{print $1}’}]

保存到文件的几种方式

set telnetoutput [ open telnetoutput w ]puts $telnetoutput file

目录 下就会创建一个telnetoutput 文件,内容就是file 不知道怎么用好

$configcmd = 'expect '.APP_PATH.'expect/getconfig'.$v['system'].'.sh '.$ip.' '.$t.' '.$u.' '.$p.' '.'enab '.$sp ;system("$configcmd > $savefile 2>&1 &");

所有内容直接保存到文件中

执行时记录日志

log_file aaa.log

在合适的位置加入这条命令,就会在执行的当前目录下生成一个aaa.log文件,但是是追加的,应该有覆盖的参数

log_file [args] [[-a] file]

如果指定了文件名,那么log_file命令会把会话的记录写入文件(从执行这条语句开始),如果没有给定任何参数,那么log_file命令会停止记
录。前面的日志文件都将被关闭。不指定文件名,还可以通过-open或是-leaveopen选项来指定Tcl文件描述符,这和spawn命令的用法一样
(参见spawn命令)。-a选项强制把log_user命令产生的输出记录到日志。默认情况下,为了在一次会话中能很方便的多次关闭日志记
录,log_file命令会把输出信息添加到文件尾,而不是覆盖原来的内容。如果想覆盖原来的内容,可以使用-noappend选项。-info选项使
log_file命令返回关于最近的non-info(非info选项)参数的描述。

expect IF的写法

if { $server_port == 21 } {    spawn telnet $server_ip} else {    spawn ssh -o StrictHostKeyChecking=no $server_user@$server_ip}if {$argc<2} {  send_user "usage: $argv0 file user1 user2 ... "  exit  } if { $flow_command == "displast300" } {for {set i 10} {$i < $argc} {incr i} {expect {">" {send "disp int [lindex $argv $i] \| in Last 300\n"}}}} 

研究半天 数字可不加双引号 字符要加双引号 而且{前要有空格,单引号不可以

【exp_send和send】
在上面的介绍中,我们已经看到exp_send命令的使用,exp_send命令是expect中的动作命令,它还有一个完成同样工作的
同胞:send,exp_send命令可以发送一些特殊符号,我们看到了\r(回车),还有一些其他的比如:\n(换行)、\t(制表符)等等
这些都是与TCL中的特殊符号相同。

spawn  ssh root@192.168.20.5expect {     "yes/no" {send "yes\r";exp_continue}      "*password:" {exp_send "123456\r"}}

send命令有几个可用的参数;
-i 指定spawn_id,这个参数用来向不同spawn_id的进程发送命令,是进行多程序控制的关键参数。
-s s代表slowly,也就是控制发送的速度,这个参数使用的时候要与expect中的变量send_slow相关联。

expect 支持正规表达式

expect -re "<.*>"puts $expect_out(buffer)exp_send "quit\r"

使用参数 -re 后面“正规内容”和C+的正规差不多。

expect -re "\[(.*)]:"  if {$expect_out(1,string)!="/bin/tcsh"} {  send "/bin/tcsh" }  send " "  expect eof 

说明:
(1)第一个expect命令现在使用了-re参数,这个参数表示指定的的字符串是一个正则表达式,而不是一个普通的字符串。对于上面这个例子里是查找一个左方括号字符(其必须进行三次逃逸(escape),因此有三个符号,因为它对于expect和正则表达时来说都是特殊字符)后面跟有零个或多个字符,最后是一个右方括号字符。这里.*表示表示一个或多个任意字符,将其存放在()中是因为将匹配结果存放在一个变量中以实现随后的对匹配结果的访问。
(2)当发现一个匹配则检查包含在[]中的字符串,查看是否为/bin/tcsh。如果不是则发送/bin/tcsh给chsh命令作为输入,如果是则仅仅发送一个回车符。这个简单的针对具体情况发出不同相响应的小例子说明了expect的强大功能。
(3)在一个正则表达时中,可以在()中包含若干个部分并通过expect_out数组访问它们。各个部分在表达式中从左到右进行编码,从1开始(0包含有整个匹配输出)。()可能会出现嵌套情况,这这种情况下编码从最内层到最外层来进行的。

范例二

#!/usr/bin/expect  # Prompt function with timeout and default.  #脚本的第一部分首先是得到运行参数并将其保存到内部变量中  set prompt [lindex $argv 0]  set def [lindex $argv 1]   set response $def  set tout [lindex $argv 2]   send_tty "$prompt: "  #send_tty命令用来实现在终端上显示提示符字串和一个冒号及空格  set timeout $tout  #set timeout命令设置后面所有的expect命令的等待响应的超时时间为$tout(-l参数用来关闭任何超时设置)。   expect " " {  set raw $expect_out(buffer)  # remove final carriage return  set response [string trimright "$raw" " "]  }  if {"$response" == "} {set response $def}  send "$response "  # Prompt function with timeout and default.  set prompt [lindex $argv 0]  set def [lindex $argv 1]   set response $def  set tout [lindex $argv 2]   

(1)send_tty命令用来实现在终端上显示提示符字串和一个冒号及空格。
(2)set timeout命令设置后面所有的expect命令的等待响应的超时时间为$tout(-l参数用来关闭任何超时设置)。
(3)然后expect命令就等待输出中出现回车字符。如果在超时之前得到回车符,那么set命令就会将用户输入的内容赋值给变脸raw。随后的命令将用户输入内容最后的回车符号去除以后赋值给变量response。
(4)如果response中内容为空则将response值置为默认值(如果用户在超时以后没有输入或者用户仅仅输入了回车符)。最后send命令将response变量的值加上回车符发送给标准输出。
注意:
(1)该脚本没有使用spawn命令。
(2)该expect脚本会与任何调用该脚本的进程交互。
(3)如果该脚本名为prompt,那么它可以用在任何C风格的shell中。

参考文献 http://blog.csdn.net/leexide/article/details/17485451

范例一种写法

#! /bin/shexpect -c "    spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/    expect {        \"*assword\" {set timeout 300; send \"$pass\r\"; exp_continue;}        \"yes/no\" {send \"yes\r\";}    }expect eof"

解释:
第二行: -c 表示可以不用与控制台交互;
第三行:spawn激活一个scp的unix程序;
第五行:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串, exp_continue表示执行下面的匹配;
第八行:表示结束。

Ø interact 很有意思的命令,可以在把操作交给用户,使用一个按键在返回给expect脚本

interact命令是Expect中非常重要的命令之一,它用来在脚本中将控制权交给用户,由用户与spawn生成的进程进行交互,比如登录ftp服务器并下载的过程中,登录ftp服务器的过程可以由用户输入自己的用户名和密码,然后用户再输入q字符将控制权交给脚本,由脚本完成后面的交互动作,这个功能的实现代码如下:
spawnftp 172.18.1.111

interact {
“d” {puts [exec date]}
“q” {return}
}

send “\r”

expect {
ftp> {send “by\r”}
}

expect {
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’m Finished\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)这个变量合并的。想看更具体的内容,请参阅第三部分

例四

#!/usr/bin/expectspawn telnet 118.88.32.203expect_before  eof eofprocexpect {-re "sername:" {exp_send "huawei\r"}-re "assword:" {exp_send "q1w2p0o9123!@#\r"}}expect eof  exit 

其中的 expect_before 是指每次expect执行之前都要执行一下某个命令或操作,没试出什么,存疑
eof eofproc 每一个expect都有一个eof过程,而且都是首先检查有没有eof事件,然后再往下检查其他的事件
参考 http://blog.csdn.net/boyishachang/article/details/8677936

例五
expect_user

expect_user命令用来匹配从用户那里的输入,之前进行匹配时,都是使用expect命令来匹配程序的输出,但这个命令则可以根据用户的输入进行匹配并完成相应的动作,看看下面的语句:

    expect_user{       -re hello       {puts stdout "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的进程发送命令,是进行多程序控制的关键参数。
-s s代表slowly,也就是控制发送的速度,这个参数使用的时候要与expect中的变量send_slow相关联

例七一直循环命令
exp_continue

这个命令一般用在动作中,它被使用的条件比较苛刻,看看下面的例子:

    spawn  ssh  root@192.168.0.1    expect  {       -timeout  60       -re  “password:” {exp_send  “word\r”; exp_continue}       -re  “TopsecOS#” { }       timeout  {puts “Expect was timeout”; return}}

在这个例子中,可以发现exp_continue命令的使用方法,首先它要处于一个expect命令中,然后它属于一种动作命令,完成的工作就是从头开始遍历,也就是说如果没有这个命令,匹配第一个关键字以后就会继续匹配第二个关键字,但有了这个命令后,匹配第一个关键字以后,第二次匹配仍然从第一个关键字开始。

例八调试命令
exp_internal

这是一条用来打开Expect调试模式的命令,它可以将整个匹配,操作过程中间发生的事情显示出来,它接受的值包括:非0值(打开调试模式)、0(关闭调试模式)、-f file(将调试内容写入文件),使用起来就像下面这样:

spawn ftp 10.11.105.15exp_internal 1expect {       -re "Name" {exp_send "ftp\r"; exp_continue}       -re "Pass" {exp_send "ftp\r"; exp_continue}       -re "ftp>" {exp_send "by\r"}}

expect EOF
注意上面的exp_internal是放在spawn命令后面的。
如果想将调试信息放入文件,则修改exp_internal 1语句,变成下面的样子:
exp_internal -f output.txt 1
具体的组合如下:
exp_internal 0 关闭诊断模式。
exp_internal 1 开启诊断模式,诊断信息输出到标准输出中。
exp_internal –f file 0 开启诊断模式,诊断信息放入文件但不输出到标准输出。
exp_internal –f file 1 开启诊断模式,诊断信息不光写入文件,也输出到标准输出。

例九其它命令
Ø exp_pid

exp_pid命令用来获取当前spawn的进程号,他支持-i选项,用来指定具体的spawn进程,使用方法就像像下面这样:
setpid [exp_pid –i $spawn_id]

Ø send_user

send_user命令用来把后面的参数输出到标准输出中去,默认的send、exp_send命令都是将参数输出到程序中去的,用起来就像这样:
send_user “Please input passwd:”
这个语句就可以在标准输出中打印Please input passwd:字符了。

Ø 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_nulls 0 #关闭自动去掉控制符的功能
remove_nulls 1 #开始知道去掉控制符的功能,这是默认值。

Ø match_max

match_max用来设置expect_out(buffer)变量的缓存大小,默认情况下expect_out(buffer)变量缓存是2000个字符,你可以设置这个大小来设置更符合实际的缓存,使用方法如下:
match_max 65535
这是一般的方法,它还支持2个选项,其中-d表示设置为默认值,也就是default的意思,-i则表示设置某个spawn_id指定的进程缓存,使用方法如下:
match_max -d 1048576
match_max -i lo_spawnid
使用-d选项一般是用于多个spawn进程同时运行的情况。

Ø trap

在脚本运行期间监听系统信号,系统信号支持3种方式:C语言方式,比如SIGINT、SIGHUP等;简略方式,比如-INT、-SIGHUP;Linux系统的kill模式,比如9、15等;监听到这些信号之后就执行规定的动作。使用方法就象这样:
trap{
send_user“bye bye\r”
exit
}SIGINT
上面的脚本中,在脚本运行期间一旦用户发送了SIGINT信号(一般都是ctrl+c),就会打印bye bye字符,然后退出脚本。信号的具体表格请查阅其他资料,而且建议使用C语言方式,因为这是目前使用最广泛的,比较容易做代码移植。

如果希望一次性监听多个信号,则可以把信号一次性的赋给trap命令,比如:
trapintproc {SIGINT SIGHUP SIGQUIT}
trap支持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 SIG_IGN { SIGINT SIGHUP SIGQUIT}   这样在脚本运行期间即使用户输入这些信号也会被忽略掉。

有时候希望在脚本前半部分忽略信号,但后半部分不忽略,使用特殊关键字SIG_DFL可以恢复这些信号的功能:
trapSIG_IGN { SIGINT SIGHUP SIGQUIT } # 取消这些信号功能
………………
trapSIG_DFL { SIGINT SIGHUP SIGQUIT } # 恢复这些信号功能

Ø exit

exit命令功能很简单,就是直接退出脚本,但是你可以利用这个命令对脚本做一些扫尾工作,比如下面这样:
exit–onexit {
execrm $tmpfile
send_user“Good bye\n”
}

Ø interpreter

interpreter用于在expect过程中调用解释器,执行到这一句之后,expect会暂时停下来显示解释器,可以在解释器中调试脚本中的内容,比如puts内部变量的值或者其他操作,到最后使用return命令就可以让脚本继续向下执行了。
调用解释器之后,可以使用更多的interpreter命令调用多个解释器,最后还是用return返回。

三、Expect选项
Ø -i选项

-i选项一般用于同时控制多个spawn进程,通过这个选项向不同spawn_id发送命令就可以同时控制多个进程了,它有二种使用方法:

1.直接使用:    spawn ftp connect    set spid_ftp $spawn_id    spawn telnet connect    set spid_telnet $spawn_id    exp_send –i $spid_ftp “ftp command”    exp_send –i $spid_telnet “telnet command”2.expect过程调用    expect {-i $spid-timeout"your timeout"-re ".+"{append result $expect_out(buffer)}-re "otherexit condition" {}}

Ø -d选项

几乎所有expect命令都支持-d选项,d代表default,也就是设置某些命令的默认值,比如:
remove_nulls –d 1
timeout –d 30

Ø -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代表regular expression,也就是正则表达式,用于expect、interact命令族中,这种类型的表达式具有匹配一切字符的能力,但掌握起来比较困难,是程序员中的一个难点,如果有兴趣了解这个强大工具,请参考我的另一个文档《正则表达式参考》。

Ø -null选项

这个选项可以用于expect和send过程,用于expect时表示连同空字符也一样做匹配(默认情况下不匹配),用于send则用于发送空字符,在send命令中还可以一次发送多个空字符,比如:send –null 3

Ø -open选项

这个选项用于spawn命令,默认情况下spawn是开启一个新进程,这个进程一般都是程序,使用-open则开启新文件,使得spawn不光可以用于进程交互,还可以与文件交互,这个选项后面的参数必须是一个文件句柄,就象这样:
setfile [open /etc/resolv.conf r]
spawn–open $file
expectnameserver {puts “it’s name server address”}

Ø -name选项

这个选项用于trap命令,用来返回信号的名称,具体使用方法请看trap命令部分。

Ø -number选项

这个选项也用于trap命令,用来返回信号代号(整数值),具体使用方法请看trap命令部分。

Ø -ignore选项

这个选项用于spawn命令,用来忽略某些特殊的信号,比如:
spawn–ignore SIGINT –ignore SIGHUP ping $host
这样在spawn执行期间用户如果发送SIGINT(ctrl+c)和SIGHUP(ctrl+d)信号,系统不会理会。

Ø -onexit选项

用于exit命令,用来在脚本退出之前做一些扫尾性的工作,具体使用方法请查看exit命令说明。

Ø -indices选项

这个选项用于expect命令中,用来开启expect的子模式匹配方式,包括expect_out(x,string) expect_out(x,start)expect_out(x,end)这3个变量族,这个选项默认情况下已经是开启的,所以一般很少使用。

Ø -info选项

用于expect_before和expect_after命令中,用来显示这2个命令实际匹配的情况,一般都是用于调试,比如下面的情况:
spawn ping 172.18.1.111 -c 2
expect_after {
time {puts time}
}
expect {
eof {puts “yes”}
}
puts [expect_after -info]
代码的输出如下:
spawn ping172.18.1.111 -c 2
PING 172.18.1.111(172.18.1.111) 56(84) bytes of data.
64 bytes from172.18.1.111: icmp_seq=0 ttl=64 time=0.263 ms
time
-gl time {putstime}
除此之外,还可以使用-all参数来获取所有spawn_id上的内容,比如:
expect_after–info –all

Ø –选项

这是终止选项,也就是表示在这个选项之后没有其他选项了,比如下面的命令:
send–s # -s是一个选项
send– -s # -s是一个字符串,表示发送-s字符
建议在所有send和expect中都使用这个选项,这样比较安全,比如:
sendunknow      # 比较危险  
    send–
unknow # 安全
上面为什么会比较危险呢?因为如果$unknow这个变量里面的值如果是以-开头,比如-know,send就会当作是一个-know选项,就会报错没有这个选项了。

四、Expect变量
expect中有很多有用的变量,它们的使用方法与TCL语言中的变量相同,比如:
set 变量名 变量值 #设置变量的方法
puts $变量名 #读取变量的方法

Ø expect_out数组

expect_out数组专用与expect命令,里面的元素包括:
expect_out(buffer)
expect_out(X,string)
expect_out(X,start)
expect_out(X,end)
expect_out(spawn_id)
上面的X字符表示从0-9的整数,具体使用下面将详细讲解。
expect_out(buffer)是一个看起来比较特殊的变量,刚刚看到的时候,会认为这是一个过程,然后用括号调用,但实际上在TCL语言中,括号也仅仅是一个字符而已,没有什么其他的意思,因此这整个字符串就是一个变量,这个变量中放置从上一次匹配到这一次匹配之间的所有返回,包括匹配字符本身。
比如你首先expect -re name,然后匹配到name之后就发送命令,再匹配expect -re password,那么expect_out(buffer)这个变量中就包括从name这个字符一直到password这个字符之间的所有设备输出。
除此之外,expect_out变量还有几个变形:
expect_out(x,string)
expect_out(x,start|end)
如果expect匹配是采用高级正则表达式的话(-re参数表示高级正则表达式方式匹配),那么每个子模式都有一个序号,序号从1-9,如:
set output “abbbcabkkkka”
expect -indices -re”b(b*).*(k+)” $output
那么:
set expect_out(0,start) ==> 1
set expect_out(0,end) ==> 10
set expect_out(0,string) ==> bbbcabkkkk
set expect_out(1,start) ==> 2
set expect_out(1,end) ==> 3
set expect_out(1,string) ==> bb
set expect_out(2,start) ==> 10
set expect_out(2,end) ==> 10
set expect_out(2,string) ==> k
set expect_out(buffer) ==> abbbcabkkkk
上面的匹配中,参数-indices表示以列表方式匹配。0代表匹配到的所有字符,相当于match,1-9则是子模式的编号。
expect_out(x,string)这样的值都不同的含义,列表如下:
expect_out(buffer)
放置上一条expect语句匹配到这一次expect语句匹配之间的所有标准输出中的内容,所以这个变量中的值是随时会改变的。
expect_out(x,string)
x是一个数字,从0到9,加起来一共是10个变量,其中0变量比较特殊,它里面保存整个expect正则表达式中匹配到的所有内容,而从1开始到9的变量中,保存正则表达式中子模式的值,也就是括在()中的那部分内容,从左往右计算。
expect_out(x,start)
x与上面的含义相同,这个变量的值是一个数值,以expect_out(1,start)为例,它里面保存第一个子模式在expect_out(buffer)变量中匹配到的时候的索引值,比如第一个子模式匹配是在expect_out(buffer)中的第10个字符开始匹配到的,那么这个变量的值就是10.
expect_out(x,end)
这个与上面的含义是相同的,只不过这里保存的是在expect_out(buffer)中匹配到的结尾的索引值。

参考文献
http://download.csdn.net/download/qq_21127151/9153601