2012-08-08 137 views
7

我有一個程序應該運行一組其他程序並收集它們的輸出用於記錄目的。只要輸出到標準輸出,一切工作都正常。在Perl中輸出日誌記錄

這使我對我兩個問題:

  1. 我怎麼能同時捕獲STDIN在一個文件中的另一個程序的STDERR

  2. 如果根本沒有輸出(或輸出僅STDERR)程序將卡住就行了:

    while (<$input>) 
    

我怎樣可以使程序等待來自另一個可能輸出程序不確定的運行時間,並且如果在程序結束執行時沒有輸出,它仍然繼續。

下面是代碼的那部分

my $pid = open (my $input, '-|', "$prog $args") 
     or push @errors, "A failute has occurred in $prog $args"; 
if(not @errors){ 
    while (<$input>){ #POSSIBLE LOCATION FOR HANG UP IF NO PRINTING IS DONE 
     if($input =~ /^END\n$/){ 
      last; 
     } 
     print $fh $_; 
    } 
} 
else{ 
    print $fh "An error has occurred with executing \"$prog $args\""; 
} 

注:$fh是用來寫我的日誌文件,我的文件處理程序,並@errors用於在我的計劃內報告錯誤。

編輯: 一個問題我想了Proc::Reliable路線經歷是,它似乎在STDOUTSTDERR後的效果有,我也需要解決這些在每次通話後運行。這導致我的代碼中的另一個問題。我正在並行運行,並且對STDOUTSTDERR的任何更改都會影響所有線程(至少使用Windows)

IO::CaptureOutput有同樣的問題對我來說,但它試圖在內部糾正STDOUTSTDERR混雜和導致以下錯誤發生:

Couldn't remove temp file 'C:\Users\SBLAKE~1\AppData\Local\Temp\m8E3pUGfOS' - Permission denied at C:/Perl/site/lib/IO/CaptureOutput.pm line 82 
+0

可能的重複[你如何在Perl中捕獲stderr,stdout和退出代碼?](http://stackoverflow.com/questions/109124/how-do-you-capture-stderr-標準輸出和最退出代碼全在一次在perl的) – daxim 2012-08-08 18:45:39

回答

1

如果從POSIX的shell啓動,那麼2>&1符號發送標準誤差同一個地方標準輸出:

some-program-to-be-logged 2>&1 | perl logger.pl -o /chosen/log.file 

標準輸出和標準錯誤都發送到Perl日誌腳本的標準輸入。

記錄器腳本中的輸入循環將掛起等待,直到有輸入讀取,或者直到管道打開時寫入的所有進程關閉管道(通常是因爲它們退出)。