你没有说你的$command,但这对我有用。
use warnings 'all';
use strict;
use IPC::Open2;
my $host = 'google.com';
my $pid = open2(\*RDR, \*WTR, "telnet $host 80 2>&1")
or die "Can't contact $host: $!";
print WTR "GET\n";
print WTR "quit\n";
while (my $line = <RDR>)
{
print $line if $. <= 10; # print only first 10 lines
}
close RDR;
waitpid($pid, 0);
my $child_exit_status = $? >> 8; # check how it went
这会打印整个页面(没有if ...)。为方便起见,打印限制为 10 行。
请仔细阅读文档IPC::Open2,因为涉及到所有这些。
open2() 返回子进程的进程ID。 [...]
open2() 在退出后不会等待并获取子进程。 [...]
这整个事件是非常危险的,因为你可能会永远阻止。 [...]
另见IPC::Open3。一个备受推崇的模块是IPC::Run,如果可能已经安装。同样出色的是Tiny::Capture,在this recent post 中使用它时看到一个非常相似的问题。两者都很有名,所以也许您的管理员可以接受它们。
我建议切换到词法文件句柄
my $pid = open2 my $read_fh, my $write_fh, "telnet $host 80 2>&1"
or die "Can't contact $host: $!";
并在整个过程中更改 RDR 和 WTR。
我不知道 Windows 环境如何影响上述情况。这些模块会给人一些信心,但我不确定open2 的票价如何。另一个可能的罪魁祸首可能是缓冲,即使我看不到它在您的代码中的情况。以防万一,你可以试试
use IO::Handle;
STDERR->autoflush(1);
STDOUT->autoflush(1);
IO::Handle 默认从 v5.16 开始加载。
还有关于此in perlfaq5 的讨论,以及进一步阅读的链接。
但是,如果您确实有缓冲问题,则很可能是在另一端,如果没有模块,这可能不容易解决。引用骆驼的话
如前所述,IO::Pty 和 Expect 模块提供了一个伪 tty 设备,为您提供行缓冲,而无需在管道末端修改程序。