進度報告/日誌資訊是否屬於標準錯誤或標準輸出?
是否有官方 POSIX、GNU 或其他指南來說明進度報告和日誌資訊(例如“Doing foo; foo done”)應該列印在哪裡?就個人而言,我傾向於將它們寫入 stderr,以便我可以重定向 stdout 並僅獲取程序的實際輸出。最近有人告訴我,這不是一個好的做法,因為進度報告實際上並不是錯誤,只有錯誤消息應該列印到 stderr。
這兩個位置都有意義,當然你可以根據你正在做的細節選擇一個或另一個,但我想知道這是否有一個普遍接受的標準。我無法在 POSIX、GNU 編碼標准或任何其他此類被廣泛接受的最佳實踐列表中找到任何特定規則。
我們有一些類似的問題,但他們沒有解決這個確切的問題:
- 何時在 shell 腳本中使用重定向到 stderr:接受的答案表明我傾向於做什麼,將程序的最終輸出保留在 stdout 上,並將其他任何內容保留到 stderr。然而,這只是作為使用者的意見呈現,儘管有論據支持。
- 使用資訊應該發送到 stderr 還是 stdout?:這是特定於幫助消息的,但引用了 GNU 編碼標準。這是我正在尋找的東西,不僅限於幫助消息。
那麼,關於應該在哪裡列印進度報告和其他資訊性消息(不是程序實際輸出的一部分)是否有任何官方規則?
Posix 定義了標準流:
在程序啟動時,應預定義三個流且無需顯式打開:標準輸入(用於讀取正常輸入)、標準輸出(用於寫入正常輸出)和標準錯誤(用於寫入診斷輸出)。打開時,標準錯誤流沒有完全緩衝;當且僅當可以確定流不引用互動式設備時,標準輸入和標準輸出流才被完全緩衝。
GNU C 庫類似地描述了標準流:
變數:FILE * stdout
標準輸出流,用於程序的正常輸出。
變數:FILE * stderr
標準錯誤流,用於程序發出的錯誤消息和診斷。
因此,除了“正常/正常輸出”和“診斷/錯誤輸出”之外,標准定義對流的使用幾乎沒有指導。在實踐中,通常將這些流中的一個或兩個重定向到文件和管道,其中進度指示器將成為問題。一些系統甚至監控
stderr
輸出並將其視為問題的徵兆。因此,純粹的輔助進度資訊在任一流上都是有問題的。與其無條件地向任一標準流發送進度指示器,重要的是要認識到進度輸出僅適用於互動式流。考慮到這一點,我建議僅在檢查流是否是互動式的(例如 with
isatty()
)或通過命令行選項顯式啟用時才編寫進度計數器。這對於依賴終端更新行為有意義的進度表來說尤其重要,例如 %-complete 條。對於某些非常簡單的進度消息(“Starting X”…“Done with X”),即使對於非互動式流,也更合理地包含輸出。在這種情況下,請考慮使用者如何與流互動,例如使用 搜尋
grep
或分頁less
或使用監視tail -f
。如果在這些上下文中查看進度消息是有意義的,那麼它們將更容易從stdout
.
POSIX將標準錯誤定義為
用於寫入診斷輸出
這不僅限於錯誤消息的使用。我會將進度資訊視為診斷輸出,因此它屬於標準錯誤。