perl -MCPAN -e 'install Expect::Simple'
与最初的 Expect 语言类似,Expect 模块的主要功能也通过 spawn,expect,send 三个方法实现。
spawn:启动目标程序
$obj = Expect->spawn( $command, @parameters
);
spawn 是 Expect 类的主要方法之一,通过 fork 和 exec 启动目标程序,若成功则返回 Expect 对象,否则返回
undef。参数 $command 指定目标程序,@parameters 为可选参数。下面是一个简单的例子:
$obj1 = Expect->spawn( "ftp 9.9.9.9"
); # 启动 ftp 进程
$obj2 = Expect->spawn( "ftp", "9.9.9.9"
); # 与上一行等效
上述两行执行结果相同,但其实际处理过程存在细微差别。一般情况下我们可以把完整的命令行 (
甚至可以是复合命令,包括命令、参数、管道符、重定向符等 ) 都写入 $command 而不指定 @parameters。
注:在 spawn 的实现中,$command 和 @parameters 都原封不动地传递给了 Perl 的 exec 函数。根据
exec 函数的说明文档,如果传递进来的是多元列表参数,exec 直接将其传递给 execvp
系统调用;如果传递进来的是标量参数或者单元列表参数,exec 函数将检查是否存在 shell 元字符 ( 如 | & ; (
) < > 等 ),若存在,则将此参数交给系统 shell 进行解析,否则将其分词后传递给 execvp
系统调用。因此如果 spawn 的是一个含有 shell 元字符的复合命令,我们一般只能将其完整写入 $command。
expect:等待特定输出
$obj->expect( $timeout, @match_patterns );
使用 Expect 对象的 expect 方法等待目标程序的特定输出。参数列表中 $timeout 设定超时 ( 以秒为单位
),@match_patterns 提供一个或多个匹配模式,如果在设定时间内目标程序输出结果和 @match_patterns
中某元素匹配则成功返回。缺省情况下 expect 使用精确匹配,若想使用正则表达式,可以在该模式元素前加 '-re' 前缀 :
$obj->expect( 10, 'match me exactly',
'-re'=>'match\s+me\s+exactly' );
标量上下文中 expect 返回匹配模式在 @match_patterns 中的位置 ( 注意下标从 1 开始 ),若不成功则返回
undef。而列表上下文中 expect 返回一个包含详细匹配信息的列表:
( $pos, $err, $match, $before, $after ) =
$obj->expect( $timeout, @patterns );
其中 $pos 就是在标量环境中的返回值,$err 是出错信息,$match 为成功匹配的字串,$before
为匹配字串之前的输出部分,$after 为匹配字串之后的输出部分。
send:发送数据
$obj->send( @strings );
当交互式程序等待用户输入时,可以使用 send 方法向其提供输入数据。需要注意,send 送出的数据可能会回显在终端上 (
具体与终端设置有关 ),此数据会进入 Expect 对象的匹配缓冲区,被下一个 expect 动作接收。为了避免 send 数据对
expect 匹配造成混乱,一般可以使用$obj->stty("-echo"
)方法关闭终端回显,或者在 spawn
前使用 $obj->raw_pty(1)将终端设定成 raw
模式 (raw 模式将关闭回显,禁止回车 - 换行符翻译 ),或者为expect
提供更加精确的匹配模式。