2013-01-23 61 views
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 $_; 
} 

但上述方案的问题是,它会以一种ReadToEnd的的()在这种情况下属于程序ping.exe的STDOUT的一部分,并允许它一次全部读取。

但是我想要做的就是在STDOUT被写出到标准输出时读取标准输出。

如果我删除了waitforpid(),那么程序会立即退出,这样也没有帮助。

这可能吗?如果是这样,请你指点我正确的方向。

更新: Drats !!!!我错过了|符号......这对于将输出从ping输入到perl脚本中是必不可少的!

回答

2

perl的一个优势(或弱点)是有多种方法可以做事。这工作:

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

只要把S/MS /毫秒/表明该数据被读取和改变 不知道到底是什么,你有错Open3

+0

谢谢更新我的问题..并接受+1 –

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来欺骗它。

相关问题