让我详细说明。
说我有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(),程序会立即退出,所以这也无济于事。
这可能吗?如果是这样,请指点我正确的方向。
更新: Drats !!!!我错过了|符号...这对于将输出管道输出到perl脚本中是必不可少的!
答案 0 :(得分: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欺骗它。
答案 1 :(得分:2)
perl的优点之一(或弱点)是,有多种方法可以做事。这有效:
perl -e 'open(F,"ping localhost|"); while(<F>) { s/ms/Milliseconds/; print $_; }'
只需输入s / ms / Milliseconds /即可显示正在读取和更改的数据 不确定Open3
到底有什么问题