2017-02-15 86 views
2

我有一個shell腳本,其stdout和stderr我要寫入日誌文件。我知道,這可以通過將stderr和stdout寫入一個文件,但也寫stderr到一個單獨的文件

sh script.sh >> both.log 2>&1 

實現不過,我也想標準錯誤同時寫入到一個單獨的文件,「error.log中」。這是可以實現的嗎?

+0

的可能的複製[?如何重定向標準錯誤和標準輸出在同一條線上的bash的不同文件(HTTP ://stackoverflow.com/questions/7901517/how-to-redirect-stderr-and-stdout-to-different-files-in-the-same-line-of-bash) –

回答

1

爲此,您需要先切換輸出和錯誤,這需要一個額外的文件描述符:

sh script.sh 3>&2 2>&1 1>&3 3>&- 

最後一個操作員關閉輔助文件描述符。

後,您可以使用tee複製錯誤流(也就是現在的標準輸入),並將它添加到您的錯誤日誌:

sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log 

之後,你就可以直接在標準輸入和標準錯誤輸出到您的組合日誌:

(sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log) >> both.log 2>&1 

命令周圍的括號對捕獲整個命令的錯誤流很重要。如果沒有它們,只會捕獲tee命令的(空)錯誤流,其餘的將繼續到終端。

注意:這不檢查文件描述符3在使用(打開)之前。在bash,那麼你可以用它來選擇一個以前未使用的文件描述符,並關閉它在過去的重定向:

sh script.sh {tmpfd}>&2 2>&1 1>&${tmpfd}- 
4

您可以使用tee將輸出複製到兩個位置。再加上一些棘手的重定向,以及...

script.sh 2>&1 >> both.log | tee -a both.log >> error.log 

這stderr重定向到標準輸出,然後標準輸出到both.log。 stderr保持不變,並且通過管道連接到tee,將其複製到兩個日誌文件中。

+0

我不明白這是如何保持在'error.log'文件中只有std-err信息。不會和'2>&1'混合在一起(並且不可區分)。 ? – shellter

+0

如果訂單被交換'>> both.log 2>&1',那麼他們會混在一起。重定向是違反直覺的。 '2>&1'並不意味着「stderr進入stdout」。這意味着「stderr會進入標準輸出的地方」。把它想成變量賦值。 'x = 5; y = x; x = 7;' - 'y'的值是5,而不是7. –

+0

嗯,呃..認爲'2>&1'的位置與標準做法交換。真是個好主意! Tnx回覆。 – shellter

相關問題