2017-06-07 48 views
0

我對stdout/stderr的理解是,腳本可以登錄到stderr,並在stdout中生成「有用的」輸出,如果需要,它將被調用進程傳送或捕獲。在bash中stderr重定向的意外行爲

實際上,這並不像我想象的那樣工作。

➜ cat test.sh 
echo diagnostic blah blah 1>&2 
echo result 

我的理解是,如果我做echo $(./test.sh),我應該得到「結果」,因爲「診斷等等等等」被髮送到stderr。不過,我得到:

➜ echo $(./test.sh)    
diagnostic blah blah 
result 

這正常工作這表明重定向標準錯誤實際工作:

➜ echo $(./test.sh 2>/dev/null) 
result 

所以我想我的輸出是如何在shell腳本處理的認識是錯誤的。我錯過了什麼?

再舉一個例子,我不希望這樣的工作:

➜ ./test.sh | grep diagnostic 
diagnostic blah blah 
+0

您如何期望能夠分辨出哪些內容被進程替換捕獲,然後由'echo'發出,並且哪些內容將通過stderr直接發送給您的TTY?畢竟,最終目的地是雙向的。 –

+0

好點 - 將編輯來演示。 – user1091042

+2

grep管只是巧合,你可以管到任何東西,它會顯示'診斷等等等等,因爲stderr被髮送到TTY,而不是通過管道。 – 123

回答

1

您的測試過程中不提供輸出和錯誤區分的任何手段。考慮改爲:

echo "stderr only here:" 
result=$(./test.sh)  ## stderr goes straight to TTY, stdout gets captured 
echo 
echo "writing the previously-captured stdout:" 
printf '%s\n' "$result" ## printf is better-defined than echo 
0

Charles Duffy是正確的 - test.sh腳本按預期工作。

我正在調查最初的問題的根本原因是簡單的 - 我被重定向從我的腳本所有的日誌輸出到stderr,但我並沒有在腳本中重定向從其他命令的輸出(在我的情況pip install ...