下面的代碼工作之類的罰款:如何從Perl管道獲得輸出?
open(PIPE, '-|', 'ant');
for(<PIPE>) {
print;
}
但是,它不會做我想做的。由於Ant構建可能需要5分鐘,我希望逐行看到輸出。 取而代之,我在整個過程結束時收到整個輸入。
用Perl調試器查看它,Perl等待'for'語句,直到Ant終止。這是爲什麼?
下面的代碼工作之類的罰款:如何從Perl管道獲得輸出?
open(PIPE, '-|', 'ant');
for(<PIPE>) {
print;
}
但是,它不會做我想做的。由於Ant構建可能需要5分鐘,我希望逐行看到輸出。 取而代之,我在整個過程結束時收到整個輸入。
用Perl調試器查看它,Perl等待'for'語句,直到Ant終止。這是爲什麼?
只是爲了完整性(問題解決了在以烏里的答覆評論中指出)的問題出現,因爲for
表達式的計算結果在列表環境中<>
運營商(see),等同於以下內容:
foreach $line (@lines = <PIPE>) {
print $line;
}
在列表上下文中,<>
操作員嘗試從其輸入讀取所有行以指派給列表 - 並且輸入來自進程,它將阻塞,直到進程結束。只有在之後它纔會進入循環體。
替代語法
while(<PIPE>) {
print;
}
相當於而是
while( $line = <PIPE>) {
print $line;
}
即,它消耗在每次循環迭代輸入中的每行,這是一個想在這種情況下該怎麼辦。
我相信問題是緩衝。你可以做出這樣的文件句柄熱(無緩衝),所以:
select PIPE;
$| = 1; # the pipe is just a coincidence. that's the variable's name
select STDOUT; # select it back
這應該PIPE禁用緩衝。我在學習Perl,5TH。另請參閱this。你也應該確保緩衝不會發生在其他地方。
編輯:OP張貼與而更換爲解決了這個問題
我想我現在明白了。 while
獲取每一行並運行循環,而for
作用就像foreach
和第一得到所有的行(它需要列表上下文)和然後環路上的行。
找到它。 問題在於'for'語句。
下面的代碼按預期工作
open(PIPE, '-|', 'ant');
while(<PIPE>) { # replacing 'for' with 'while'
print;
}
我不知道原因,但現在它正在發揮作用。
要理解原因,請參閱http://stackoverflow.com/questions/585341/ – Joe 2010-05-23 21:15:23
如果您回答了自己的問題,最好編輯原始問題並添加答案,而不是發表回覆。 – 2010-05-23 22:42:45
@Barry Brown發佈你自己的答案,並接受它,如果沒有人提供更好的答案被接受(heh)實踐SO。 http://meta.stackexchange.com/questions/12513/stackoverflow-should-i-answer-my-own-question-or-not – hobbs 2010-05-24 01:16:41
緩衝可能是問題,但有問題的緩衝區在Ant方面,而不是Perl的方面。您只需要關閉輸出管道而不是輸入管道的緩衝。你需要找到一些方法告訴Ant不要緩存它的輸出。你無法解決Perl方面的問題。 – cjm 2010-05-23 21:00:18