Expect: 自动化交互式命令行程序

@ 2011-07-02 18:30:24
标签:

    expect是一个基于Tcl的用于自动化交互式命令行程序的工具。它包括expect程序和libexpect程序包。

    一个常见的应用场景,比如自动登录某台机器并执行命令:

    spawn telnet $remote_server  ; # 启动外部程序
    expect "username:"           ; # 等待匹配字符串 "username"
    send "$my_user_id\r"         ; # 模拟用户输入用户名
    expect "password:"           ; # 等待输入密码提示
    send "$my_password\r"        ; # 输入登录密码
    expect "%"                   ; # 等待出现命令行提示符
    send "$my_command\r"         ; # 输入要执行的命令
    expect "%"                   ; # 等待命令执行结束,出现命令提示符
    
    set results $expect_out(buffer) ; # 获得外部程序的所有输出
    send "exit\r"                ; # 输入exit退出外部程序
    expect eof                   ; # 等待外部程序退出
    

    Expect其实是一个提供了扩展的Tcl程序。它在支持Tcl内置的命令的同时,提供了一组新的命令用于控制外部进程。

    expect 命令的用法

    expect 很像Tcl内置的switch命令,可以同时指定多个匹配字符串和匹配格式。

    expect {
      "pattern*"      {...}  
      -gl "pattern*"  {...}
      -re "pattern.*" {...}
      -ex "pattern*   {...}
    } 
    
    • 默认是通配符匹配(glob)
    • 如果pattern以'-'开头,可以显示地指定 -gl选项
    • -re用来指定使用正则表达式匹配(regexp)
    • -ex用来指定使用完全匹配,即要求与指定的模式完全一样
    • timeout 是内置的特殊模式,用于匹配超时的情况。
    • eof 这个内置的特殊模式,用于匹配EOF,通常是外部命令结束
    • default匹配timeout或者eof

    如果没有指定timeout模式,则超时的情况下,执行的默认命令为空,即什么都不做。

    超时的设置默认是10秒钟。可以通过全局变量timeout来改变超时时间。设置为"-1"的时候则无限等待。

    Tips

    Prompt: 命令提示符

    用expect与Shell交互的一个常见问题是不同用户的命令行提示符(prompt)可能会很不一样。

    比如可能看起来像下面这样

    • [223]root@cyborg:/usr/local/etc>
    • 81 myhost >
    • [user@host ~]$
    • ... ...

    一个常见的做法是用正则表达式去匹配

    set prompt {[\r\n]?[^\r\n]+[%#>\$] ?$}
    expect {
      -regexp $prompt { puts "Match" }
      timeout         { puts "timeout" }
    }
    

    网络资源

    标签:

      分享到:
      comments powered by Disqus

      21/23ms