如何使用Expect.pm(Perl)显示所有输入和输出?
这里是一个小型Perl服务器。它显示(1),接受一行输入,然后显示(2),等等。如果您键入“error”或“commit”,它会给出一条自定义消息。如果您键入“退出”,它将退出。否则,它将无休止地获取输入行如何使用Expect.pm(Perl)显示所有输入和输出?,perl,stdout,expect,Perl,Stdout,Expect,这里是一个小型Perl服务器。它显示(1),接受一行输入,然后显示(2),等等。如果您键入“error”或“commit”,它会给出一条自定义消息。如果您键入“退出”,它将退出。否则,它将无休止地获取输入行 use strict; use warnings; $|++; my $counter = 1; print "($counter) "; while (<STDIN>) { chomp; if ($_ eq "error") {print "Error on co
use strict;
use warnings;
$|++;
my $counter = 1;
print "($counter) ";
while (<STDIN>) {
chomp;
if ($_ eq "error") {print "Error on command #$counter\n";}
if ($_ eq "commit") {print "Committing data\n";}
if ($_ eq "exit") {print "Exiting program...\n"; exit;}
$counter++;
print "($counter) ";
}
我想要的是能够从头到尾存储整个会话,包括服务器脚本生成的所有内容,以及Expect.pm脚本发送的所有内容
也就是说,我希望我的客户机脚本能够像这样返回输出,如果手动运行并与服务器脚本交互,您将看到:
(1) This is the first command
(2) Here is the second command
(3) error
Error on command #3
(4) commit
Committing data
(5) This is the last command
(6) exit
Exiting program...
(1) 这是第一个命令
(2) 这是第二个命令
(3) 错误
命令#3出错
(4) 承诺
提交数据
(5) 这是最后一个命令
(6) 出口
正在退出程序。。。
但是,运行客户端脚本得到的标准输出显示如下所示:
This is the first command
(1) (2) Here is the second command
error
(3) Error on command #3
(4) commit
This is the last command
Committing data
(5) (6) exit
Exiting program...
这是第一个命令
(1) (2)这是第二个命令
错误
(3) 命令#3出错
(4) 承诺
这是最后一个命令
提交数据
(5) (6)出口
正在退出程序。。。
由$exp->log_文件(tmp/expect.out)指定的文件显示:
(1) (2) (3) Error on command #3
(4) Committing data
(5) (6) Exiting program...
(1) (2)(3)命令错误#3
(4) 提交数据
(5) (6)退出程序。。。
我试着记录命令本身的各种组合,以及$exp->expect()返回的匹配前和匹配后变量。但到目前为止,我还没有得到正确的组合。这似乎是一个非常笨拙的方式来获得我想要的
那么,捕获Expect.pm会话的整个过程的最佳实践是什么
感谢所有能帮忙的人 在命令行上运行时,服务器会打印
(1)
立即输入并等待输入
但是,当您创建Expect
对象时,实际上是在设置PTY(伪终端)。您生成的任何进程的stdin和stdout都将连接到此PTY,而不是您的shell所连接的TTY。这意味着由Expect
对象决定是否显示派生进程的输出;它不会自动显示
当您spawn
一个进程时,Expect
对象保存在输入缓冲区中的任何输出上。当您向进程发送
字符串时,生成的任何附加输出都将读入缓冲区。如果PTY已启用回显(默认设置),则您发送的字符串将回显,但Expect
对象缓冲区的内容将不会回显
调用expect
方法时,expect将等待输入缓冲区中出现匹配字符串。如果在超时过期之前找到匹配项,expect
返回并打印匹配字符串
因此,您只需在发出第一个命令之前调用expect
,如下所示:
This is the first command
(1) (2) Here is the second command
error
(3) Error on command #3
(4) commit
This is the last command
Committing data
(5) (6) exit
Exiting program...
服务器
输出
(1)foo
(2) 酒吧
(3) 巴兹
(4)
请注意,这与手动与进程交互时使用的过程完全相同:等待提示,然后键入命令。为什么您希望在打印
时获得(1)这是第一个命令,在将它发送到服务器程序之前发送到STDOUT
?您得到的输出正是我所期望的(双关语不是故意的)。@ThisSuitesBlackNot:如果只是将第一个命令预先添加到输出变量或文件中,那就很容易了。更棘手的问题是,无论是STDOUT还是$exp->log_文件都不包含格式化为您自己与程序交互时实际显示的数据。标记为“它应该看起来像这样”的块是我在客户端脚本中不知道如何重建的块。因此,我猜“它应该看起来像这样”的意思是,“我希望它看起来像这样。”为什么不只是print”($counter)$\代码>在您的服务器中?。
use strict;
use warnings;
$| = 1;
my $counter = 1;
do {
print "($counter) ";
$counter++;
} while (<>);
use strict;
use warnings;
use Expect;
$| = 1;
my $exp = Expect->new;
my $server = './expect_server';
$exp->spawn($server);
my @commands = qw(foo bar baz);
foreach my $command (@commands) {
$exp->expect(1, '-re', '\(\d+\)');
$exp->send("$command\r");
}
$exp->soft_close;