2013-01-23 104 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來欺騙它。

相關問題