windows下expect使用小结

来源:互联网 发布:预测炒股票软件哪家好 编辑:程序博客网 时间:2024/06/06 20:14

最近因为学习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


0 0
原创粉丝点击