0

让我详细说明。

说我有 perl 程序

(这是从 perl http://perldoc.perl.org/perlfaq8.html#How-can-I-open-a-pipe-both-to-and-from-a-command%3f无耻地复制和编辑的 )

 use IPC::Open3;

 use Symbol qw(gensym);   

 use IO::File;
 local *CATCHOUT = IO::File->new_tmpfile;
 local *CATCHERR = IO::File->new_tmpfile;

 my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "ping -t localhost");

 #waitpid($pid, 0);   

seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;

 while( <CATCHOUT> ) {

print $_;
}

但上述程序的问题在于,在这种情况下,它会读取属于程序 ping.exe 的 STDOUT 的一种 readtoEnd(),并允许一次读取所有内容。

但是我想要做的是在将 STDOUT 写入 STDOUT 时读取它。

如果我删除 waitforpid() 那么程序会立即退出,所以这也无济于事。

那可能吗 ?如果是这样,请您指出正确的方向。

更新:德拉斯!!!!我错过了| 符号...这对于将输出从 ping 输出到 perl 脚本至关重要!!!

4

2 回答 2

3
use IPC::Open3 qw( open3 );

open(local *CHILD_STDIN, '<', '/dev/null') or die $!;

my $pid = open3(
   '<&CHILD_STDIN',
   my $child stdout,
   '>&STDERR',
   'ping', '-t', 'localhost',
);

while (<$child_stdout>) {
   chomp;
   print("Got: <<<$_>>>\n");
}

waitpid($pid, 0);

但这可以写成

open(my $ping_fh, '-|', 'ping', '-t', 'localhost') or die $!;

while (<$ping_fh>) {
   chomp;
   print("Got: <<<$_>>>\n");
}

close($ping_fh);

这只是显示了正确的用法。如果这些不起作用,这是一个不相关的问题:ping在未连接到终端时正在缓冲它的 IO。您可以使用伪 tty 来欺骗它。

于 2013-01-23T09:34:39.063 回答
2

perl 的优点(或缺点)之一是做事的方法不止一种。这有效:

perl -e 'open(F,"ping localhost|"); while(<F>) { s/ms/Milliseconds/; print $_; }'

只需输入 s/ms/Milliseconds/ 以显示正在读取和更改数据 不确定 Open3 到底有什么问题

于 2013-01-23T09:11:07.377 回答