Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Expect.pm(Perl)显示所有输入和输出?_Perl_Stdout_Expect - Fatal编程技术网

如何使用Expect.pm(Perl)显示所有输入和输出?

如何使用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

这里是一个小型Perl服务器。它显示(1),接受一行输入,然后显示(2),等等。如果您键入“error”或“commit”,它会给出一条自定义消息。如果您键入“退出”,它将退出。否则,它将无休止地获取输入行

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;