您的位置:首页 > 编程语言

windows下expect使用小结

2014-07-30 20:17 274 查看
最近因为学习tcl脚本语言,需要用到expect扩展包,结合网上的资料和自己的学习情况做一下整理。

expect是一种基于TCL的解释型脚本语言,能够实现自动和交互式任务进行通信,而无需人的干预。expect由一系列expect-send对组成:expect等待输出中输出特定的字符,然后发送特定的响应。

Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。expect相关软件包版本有多个,如expect-tcl8.3、expectk、expect-dev等,可根据自身需求选择安装。

我们工作中主要利用expect扩展包来实现telnet到远程终端、输入命令来控制终端的运行,在执行一些重复性工作或是要输入大量配置时相当方便。

一、expect的一个小例子(windows环境下)

package require Expect    

spawn telnet 192.168.86.172

set telnet $spawn_id

expect "enable passward: "

send "admin\r"

expect "#"

send "config terminal\r"

解释:这是一个.tcl文件中的一段脚本,首行package require Expect声明加载expect包,然后就可以调用expect相关命令了。

"spawn"用来启动脚本和命令的会话,常用的命令有telnet、ssh、rlogin等,这里启动的是telnet命令,实际上命令是以衍生子进程的方式来运行的。另外值得说明的是,只有spawn的内容才能被expect捕获到。

"expect"对执行command后的输出进行匹配检测,可使用正则表达式和通配符等。

"send"用于发送command。

二、expect的语法以及注意点

脚本都有相似之处,Expect是基于TCL的,有以下几个地方需要注意: 

1)“{”与前面的字符必须空一格,否则会被解释器认为是与前面字符是同一个词。 

2)一条命令结尾的“;”是可有可无的,但如果同一行写来多条命令,则必须以“;”分隔,否则会被误认为只有一条命令。 

3)expect检测的双引号中的字符串,若有多行,除前引号后面的那行外,其余的均需要顶格写,否则空格也会被匹配进去,或者前面用通配符“*”来匹配也行。 

4)如果发现脚本挂在了某个点上,可以试着在前一个send前面增加一小会儿sleep时间。因为在收到提示后,一系列的程序(rn, ksh,zsh,telnet,etc.)和设备抛弃或忽略的按键等响应的“太快”了。 

5)某些程序每次产生的结果都是不一样的,此时最好用通配符来匹配。 

三、流程控制

expect除了基于TCL的if/else等条件判断外,其自身也提供来expect流程控制的功能,示例如下: 

send "sudo -s" 

expect    {   "password: "     {send "vmkid\r"; exp_continue} 

                      "~# "                {puts "------break----"} 



意思是发送“sudo -s”命令后,有两种可能的输出,如果输出为“password:“,则执行后面所跟的”{}“中的命令,发送密码并跳出此次循环,直到输出结果为”#
“才跳出整个expect循环。另外,expect与if/else等也可循环嵌套使用。 

四、过程

某些代码有时是需要重复操作的,比如设备在某些特定的场合下可能需要反复重启等,此时我们可以将其写在某一个过程中,直接调用该过程,以减少和简化代码。 

proc SystemReset {x} { 

if {$x == 1} { 

spawn adb shell 

expect "~# " 

send "reboot\r" 

expect "*" 

} else { 





如上,在需求重启手机时,我们只要调用”SystemReset 1"便可以了。 

五、输出日志

log_file [文件名]

这个命令让expect在你设置的文件中记录输出信息。必须注意,这个选项并不影响控制台输出信息,不过如果你通过crond设置expect脚本在半夜运行的话,你就确实可能需要这个命令来记录各种信息了。例如:log_file expect.log

log_user 0/1

这个选项设置是否显示输出信息,设置为1时是缺省值,为0 的话,expect将不产生任何输出信息,或者说简单地过滤掉控制台输出。必须记住,如果你用log_user 0关闭了控制台输出,那么你同时也就关闭了对记录文件的输出。

六、超时

expect的timeout时间, 是以秒为单位, 如果设置为0, 是根本就不等待, 设置为-1, 是永远等待. 

set timeout 30 

附录:expect的程序介绍

1,主要程序源文件概述(在编译过程中提取)

exp_command.c   --->

expect.c   --->

exp_inter.c   --->

exp_regexp.c   --->

exp_tty.c   --->

exp_log.c   --->

exp_main_sub.c   --->expect 的主程序(expect/expectk共用)

exp_pty.c   --->

exp_trap.c   --->

exp_strf.c   --->

exp_console.c   --->

exp_glob.c   --->

exp_win.c   --->

exp_clib.c   --->

exp_closetcl.c   --->

exp_memmove.c   --->

exp_tty_comm.c   --->

exp_chan.c   --->

Dbg.c   --->

pty_termios.c   --->

exp_select.c   --->

exp_event.c   --->

exp_main_exp.c   --->expect 主程序(壳)

exp_main_tk.o   --->expectk主程序(壳)

2,需要关照的Tcl命令

exp_close    --->关闭exp_spawn打开的链接   --->Exp_command.c  exp_init_most_cmds

exp_continue    --->重新执行expect   --->未在expect源代码中定义

exp_disconnect     --->与儿子进程断开关联   --->Exp_command.c

exp_exit     --->重写了Tcl默认的exit命令   --->Exp_command.c

exp_fork     --->克隆 当前的expect进程  --->Exp_command.c

exp_getpid     --->获取expect进程id   --->Exp_command.c

exp_inter_return     --->   --->Exp_command.c

exp_interact     --->   --->Exp_inter.c

exp_internal     --->   --->Exp_command.c

exp_interpreter     --->   --->Exp_command.c

exp_log_file     --->设置记录会话路径文件   --->Exp_command.c

exp_log_user     --->关闭和打开交互过程的标准输出   --->Exp_command.c

exp_match_max     --->设置交互buff的大小,默认2000   --->Expect.c

exp_open     --->   --->Exp_command.c

exp_overlay     --->   --->Exp_command.c

exp_parity     --->   --->Expect.c

exp_pid     --->   --->Exp_command.c

exp_remove_nulls     --->   --->Expect.c

exp_send     --->expect发送命令   --->Exp_command.c

exp_send_error     --->发送错误输出   --->Exp_command.c

exp_send_log     --->发送到log文件   --->Exp_command.c

exp_send_tty     --->   --->Exp_command.c

exp_send_user     --->   --->Exp_command.c

exp_sleep     --->expect等待(秒)   --->Exp_command.c

exp_spawn     --->启动外部进程   --->Exp_command.c

exp_strace     --->   --->Exp_command.c

exp_stty     --->   --->Exp_tty.c

exp_system     --->   --->Exp_tty.c

exp_timestamp     --->   --->Expect.c

exp_trap     --->   --->Exp_trap.c

exp_version     --->   --->Exp_main_sub.c

exp_wait     --->等待exp_spawn启动的进程结束退出   --->Exp_command.c

expect     --->expect主要命令   --->Expect.c

expect_after     --->   --->Expect.c

expect_background     --->   --->Expect.c

expect_before     --->   --->Expect.c

expect_tty     --->   --->Expect.c

expect_user     --->   --->Expect.c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息