2014-02-22 118 views
2

我有一個Perl腳本,說「process_output.pl」這是在下列情況下使用:行緩衝讀取在Perl

long_running_command | 「process_output.pl」

的process_output腳本,需要像Unix的「三通」命令,因爲它得到生成的轉儲「long_running_command」到終端的輸出,並且除了捕捉輸出到文本文件,並且在「long_running_command」結尾處,以文本文件作爲輸入分叉另一個進程。

我目前看到的行爲是,「long_running_command」的輸出只有在完成而不是在生成時轉儲輸出時纔會轉儲到終端。我需要做一些特別的事情來解決這個問題嗎?

基於我在其他幾個stackexchange帖子的閱讀,我試圖在 「process_output.pl」 下面,沒有太大的幫助:

  1. select(STDOUT); $| =1;
  2. select(STDIN); $| =1; # Not sure even if this is needed
  3. use FileHandle; STDOUT->autoflush(1);
  4. stdbuf -oL -eL long_running_command | "process_output.pl"

有關如何繼續的任何指示 進一步。

感謝 AB

回答

4

這很可能是與第一個進程的輸出問題被緩衝,而不是你的腳本的輸入。最簡單的解決辦法是使用unbuffer命令(我相信這是expect包的一部分)的嘗試,像

unbuffer long_running_command | "process_output.pl" 

unbuffer命令將禁用,通常發生在輸出定向到非交互的緩衝地點。

1

這將是long_running_processing的輸出處理。它很可能會使用stdio - 它會在輸出之前查看輸出文件描述符所連接的內容。如果它是一個終端(tty),那麼它通常會輸出基於行的數據,但在上面的例子中 - 它會注意到它正在寫入一個管道,因此會將輸出緩衝到較大的塊中。

您可以通過使用控制緩衝在自己的過程中,你表現出

select(STDOUT); $| =1; 

這意味着東西,你的程序打印到STDIO,沒有緩衝的 - 它沒有任何意義這樣的輸入,因爲你控制了多少緩衝 - 如果你使用sysread(),那麼你正在讀取無緩衝的,如果你使用像<$fh>這樣的結構,那麼perl將等待,直到它有一個「整行」(它實際上讀取到下一個輸入行分隔符在變量$/中定義,默認情況下是換行符)),然後它將數據返回給您。

unbuffer可用於「禁用」輸出緩衝,它實際上所做的是使輸出過程認爲它正在與tty(通過使用僞tty)通信,因此輸出過程不會緩衝。