簡體   English   中英

將 stdout 和 stderr 顯示到控制台和文件,將 stderr 着色為紅色並在生成時顯示 stdout 和 stderr

[英]Display stdout and stderr to both console and file, color stderr red and display stdout and stderr as they are being produced


我嚴格要求 *stdout* 和 *stderr* 同時重定向到控制台和文件,其中 *stderr* output 被塗成紅色。
此外,*stdout* 和 *stderr* 行應該按照它們產生的順序顯示(我會更好地解釋我的意思)。
我的問題是在 bash 腳本中完全實現這一點,因為每個單獨的步驟並不是真正的大挑戰。


a) 在控制台和文件中顯示 *stdout* 和 *stderr*
有很多信息如何實現這一點。 就像是:
 mycommand 2>&1 | tee mylog.log

但是,如前所述,我需要的還不止這些。

b) 在控制台上將stderr 塗成紅色
同樣,不是一個大問題:

 exec 3>&1 mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of command exec 3>&- #housekeeping, close file handle 3

基本上,每條標准輸出行都被注入 ansi 代碼以將它們變為紅色。 當然,需要一個與 ansi 兼容的控制台——我正在為 Windows 使用 cmder/ConEmu。

無論如何,output 正是我所需要的。 事實上,這就是我所說的“ stdoutstderr按它們的生成順序顯示”的意思:

正確的輸出 (圖 1 - 右輸出)

c) 聯合起來
這也應該很簡單,例如:

 myfunc() { exec 3>&1 set -o pipefail mycommand 2>&1>&3 | sed $'s,.*,\e[31m&\e[m,' EXIT_CODE=${PIPESTATUS[0]} #exit status of $EXEC_COMMAND exec 3>&- #housekeeping, close file handle 3 echo exit_code: $EXIT_CODE } myfunc | tee mylog.log echo "EXIT_CODE: $EXIT_CODE"

但這並不簡單。 至少對我來說不是,即因為現在 mycommand 的stderr僅在我退出我的應用程序后才顯示(它是在運行“mycommand”時執行的):

錯誤的輸出 (圖 2 - 錯誤輸出)

此外,作為副作用,我無法設法在 function 之外獲取 EXIT_CODE 值。
我看到了類似的問題,但似乎都與在子 shell 中運行的 while 循環、“重定向”和\或“進程替換”有關。 我仍然無法解決我的具體問題。


所以,我的問題是:

  1. 如何將標准輸出和標准錯誤同時用於控制台和文件,有紅色的標准錯誤行和“標准輸出和標准錯誤在生成時顯示”(見圖 1)?
  2. 如何獲取 function 主體之外的 EXIT_CODE 值?


感謝您的時間!

即因為現在 mycommand 的 stderr 僅在我退出我的應用程序后才顯示

如何將標准輸出和標准錯誤同時用於控制台和文件,有紅色的標准錯誤行和“標准輸出和標准錯誤在生成時顯示”(見圖 1)?

當 output 不是終端時,程序的 stderr 和 stdout 都會變成塊緩沖。 stdout是塊緩沖的,因為mycommand沒有輸出到終端,並且sed s output 不是終端,它正在輸出 stderr,因此 stderr 也成為塊緩沖。 配置您的程序以將其 stdout/stderr 配置為行緩沖,或者您可以使用stdbuf -oL -eL設置初始緩沖並使用sed -ustdbuf -oL sed

如何獲取 function 主體之外的 EXIT_CODE 值?

  1. 創建一個臨時文件。
  2. $EXIT_CODE寫入臨時文件。
  3. 閱讀那個文件。

或從您的 function 返回退出代碼並像您一樣使用 PIPESTATUS 。

myfunc() {
  {
      stdbuf -oL -eL mycommand 2>&1 >&3 | sed -u $'s,.*,\e[31m&\e[m,'
      EXIT_CODE=${PIPESTATUS[0]}
  } 3>&1  
  echo exit_code: $EXIT_CODE
  return "$EXIT_CODE"
}
myfunc | tee mylog.log
echo "EXIT_CODE: ${PIPESTATUS[0]}"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM