Stdout

用於調試和管道輸出(日誌記錄、指標等)的附加文件描述符

  • November 7, 2020

對於 bash 腳本項目,我將人類可讀的日誌資訊寫入 stdout/stderr。此外,我想將格式化的指標寫入預設情況下將被丟棄但可以重定向以進行管道處理的第三個流。建議使用附加文件描述符的方法嗎?

exec 3> /dev/null
echo "This is stdout"
echo "This is stderr" >&2
echo "This is fd3" >&3

我很好,第三行在正常情況下不顯示。但是,當在某個工具鏈中使用時,我想通過管道傳輸這些消息。簡單的例子:

$ bash example.sh 3>&1
This is stdout
This is stderr

第三行不顯示為控制台輸出。

我究竟做錯了什麼?有針對這個的解決方法嗎?是否建議使用另一種方​​法?

Fd 3 綁定到/dev/null第一行,因此第三個 Echo 不可避免地會將其標準輸出重定向到/dev/null.

相反,通過檢查/proc/self/fd/3. 如果沒有,則將其綁定到/dev/null. 如果是,請不要理會它。

[ -e /proc/self/fd/3 ] || exec 3> /dev/null
echo "This is stdout"
echo "This is stderr" >&2
echo "This is fd3" >&3
$ ./example.sh 3>&1
This is stdout
This is stderr
This is fd3
$ ./example.sh
This is stdout
This is stderr

如果第三個 Echo 實際上是一個寫入大量輸出的命令,則更有效的替代方法是僅在 Fd 3 打開時才觸發該命令。

echo "This is stdout"
echo "This is stderr" >&2
[ -e /proc/self/fd/3 ] && echo "This is fd3" >&3

另一種可能性是始終通過 Fd 3 重定向到文件或 FIFO,並且僅在呼叫程序中需要時才讀取它,但這也意味著如果不使用該輸出,則會造成不必要的時間損失。

引用自:https://unix.stackexchange.com/questions/618470