IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

深入Perl的expect

扶凯 2009-10-25 22:36:32 累计浏览 2,827 次
本机暂存

    Perl实在大方便了,如果用它来玩expect,是相当的好,不用在学一次expect的语法.只要了解perl就行了. 下面是我看官方的文章还有自己使用中总结的一些经验.呵呵,我有新的心得就会来更新的….

    perl的expect基本使用方法.

以下是代码片段:

$exp = new Expect;  #new一个Expect.
$exp->spawn($command,@params);  #fork和exec一个新进程用来执行$command命令.
$exp->expect($timeout,$content); #'-re'.在$timeout内,期待出现包含$content内容的正则表达式,如果不加re默认是精确匹配,也可以使用正则表达式,expect($timeout,re=>'').
$exp->send($string);  #向终端发送字符
$exp->debug(0|1|2);  #打印debug 信息,不同的数字表示不同的bug级别
$exp->interact();   #和用户进行交互,把控制权转交给用户
$exp->soft_close();  #软关闭,直到$timeout时间到达,才关掉该进程
$exp->hard_close();  #硬关闭,立刻关闭该进程
$exp->match();   #返回匹配的结果
$exp->match_number(); #返回匹配的个数
$exp->send_slow(); # 就是让command慢慢敲进去..
$exp->stty(); #它和外部命令 stty 类似,设定 terminal 的模式,-raw 还是 -cooked。开关回显 echo 和 -echo。

    exp_continue 一般在 expect 命令中使用,它可以避免写第二次 expect 命令,即如果匹配上某个模式,然后需要做一些事情(如输入密码什么的),之后需要继续匹配,因此需要第二次 expect 命令。exp_continue 可以重复本次 expect 命令,因此也就不需要再次写一个 expect 命令,而可以将两个写在一起。

    我们想让程序只在后台跑就行了,不会跑到前面来影响我们.所以我们需要expect的关掉终端显示的功能.

以下是代码片段:

$Expect::Log_Stdout = 0;
$exp->log_stdout(0);

    注:0为关掉显示,1为打开

    希望expect一直等到某个字符出现需要怎么样做

以下是代码片段:
$exp->expect(undef,sub {})

    如果不希望expect等,就使用$exp->expect(0),这样当前如果有这个字符就成功,没有就跳过.

    取得expect的命令行中有输出,使用before来取得数据来进行处理

以下是代码片段:
my $read = $exp->before();
print $read;

    注意,这个得到的内容,是从expect中匹配到的内容.

    在使用expect时,日志中有很多特别的符号,使用下面这个terminal type的设定,就会好了. 不知为什么,日志文件中会有很多^[ ,^G之类的字符,如果用了下面的参数就行了,只有一个^M,这个用dos2unix就行了

以下是代码片段:
$ENV{TERM} = "xterm";

    打开内部调试,这样可以让后续命令的诊断信息发送到 Expect 所控制的 stderr,这样可以显示出比如$exp->expect()中的内容是否匹配.这样可以显示看到显示的字符,方便调试匹配规则,

以下是代码片段:
$exp->exp_internal(1);

    注意:internal这个必须写到spawn后面 打开debug模块,可以显示连接的过程,进程的退出之类的状态

以下是代码片段:
$exp->debug(3);

    记录expect的日志到一个文件

以下是代码片段:
$exp->log_stdout(1);
$exp->log_file("output.log"); #注意,这句一定要写在Expect->spawn之后,不然expect会没有日志输出
中间发送和匹配之类的过程.......
$exp->log_file(undef);

    在expect时,追加日志到一个文件

以下是代码片段:
$exp->log_file("filename");

    默认是追加,如果要修改就用

以下是代码片段:
$exp->log_file("filename", "w");

    在perl的expect中怎么发送控制字符,

    比如

以下是引用片段:
    ctrl+c control-G $exp->send("\\cG");
    control-c $exp->send("\\cC";); 

    我设置了一个终端大小,但是修改窗口大小后,我的Expect不能发现窗口改变. 主要是远程不能抓到本地的WINCH"window size changed"的信号,当我修改我本地终端大小时需要传送信息给spawn.

以下是代码片段:
  my $exp = new Expect;
  $exp->slave->clone_winsize_from(\*STDIN);
  $exp->spawn("ssh somehost);
  $SIG{WINCH} = \&winch;
 
  sub winch {
    $exp->slave->clone_winsize_from(\*STDIN);
    kill WINCH => $exp->pid if $exp->pid;
    $SIG{WINCH} = \&winch;
  }
 
  $exp->interact();

    一个简单的Perl使用Expect自动登陆服务器的实例

以下是代码片段:
#!/usr/bin/perl
use Expect;
$Expect::Log_Stdout = 1;
 
$ENV{TERM} = "vt100";
 
my ($host,$pass) = ("host","passwd");
my $exp = Expect->new;
$exp = Expect->spawn("ssh -l root $host");
$exp->log_file("output.log", "w");
$exp->expect(2,[
                    qr/password:/i,
                    sub {
                            my $self = shift ;
                            $self->send("$pass\n");
                            exp_continue;
 
                        }
                ],
                [
                    ’connecting (yes/no)’,  
                    sub {
                            my $self = shift ;
                            $self->send("yes\n");
                         }
                ]
            );
#$exp->interact() if ($exp->expect(undef,’#’));
$exp->send("uptime\n") if ($exp->expect(undef,’#’));
$exp->send("exit\n") if ($exp->expect(undef,’#’));
$exp->log_file(undef);

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. WEB系统需要关注的一些点 (累计阅读 18,218)
  2. 批量添加主机到cacti+nagios的监控报警系统中 (累计阅读 14,991)
  3. Linux命令行里的“瑞士军刀” (累计阅读 11,584)
  4. perl更新/修改/删除文本文件内容 (累计阅读 10,648)
  5. rsync同步的艺术 (累计阅读 9,598)
  6. 应该知道的Linux技巧 (累计阅读 8,947)
  7. 你可能不知道的Shell (累计阅读 8,313)
  8. perl大牛flw传说 (累计阅读 7,714)
  9. 完全用命令行工作 -- 一年后的思考 (累计阅读 7,467)
  10. AWStats是一个基于Perl的WEB日志分析工具。 (累计阅读 7,175)