我有一個在stderr和上生成輸出的程序stdout。
我需要通過管道傳輸這兩個不同的命令,但我也想繼續在終端上看到它們。
所以我嘗試了這樣的事情作為概念證明:
#!/usr/bin/env bash
set -e
function generate_output() {
echo This message goes to stderr 1>&2
echo This message goes to stdout
}
generate_output \
1> >(tee <&0 >(cat > out.log)) \
2> >(tee <&0 >(cat > err.log))
cat > out.log 是一個虛擬命令,當我弄清楚如何使其作業時,它將被其他東西替換。
它幾乎有效:
$ cat err.log
This message goes to stderr
我在終端上看到了輸出。
到現在為止還挺好 !
但 :
$ cat out.log
This message goes to stdout
This message goes to stderr
為什么“stderr”訊息最終出現在 out.log 中?
更讓我困惑的是,如果我洗掉 tee 命令,日志檔案將包含預期的結果(但隨后我丟失了終端輸出)
#!/usr/bin/env bash
set -e
function generate_output() {
echo This message goes to stderr 1>&2
echo This message goes to stdout
}
generate_output \
1> >(cat > out.log) \
2> >(cat > err.log)
uj5u.com熱心網友回復:
兩個tees 都在寫入標準輸出。第一個沒問題,但第二個有問題,因為2>處理重定向時1>已經重定向了標準輸出。這意味著第二個tee不是寫入終端,而是寫入第一個tee行程。哎呀!
修復它的一種優雅方法是讓每個tees 寫入它們正在讀取的 fd。添加>&2到第二個將解決問題。因為我可以告訴你像并行結構,你也可以>&1在第一個結構中添加一個顯式。
如果腳本輸出有任何下游消費者,這將具有保留 stdout 和 stderr 分離的良好效果。
generate_output \
1> >(tee <&0 >(cat > out.log) >&1) \
2> >(tee <&0 >(cat > err.log) >&2)
然后,您可以消除一些冗余:
<&0將 stdin 重定向到 stdin,它什么都不做。>(cat >file)是一種復雜的寫作方式file。只需將out.log和err.log直接傳遞給即可獲得相同的效果tee。
generate_output \
1> >(tee out.log >&1) \
2> >(tee err.log >&2)
uj5u.com熱心網友回復:
錯誤正在發生,out.log因為tee正在繼承重定向的標準輸出。因此,當它寫入其標準輸出時,它會進入第一個tee行程。
更改重定向的順序以解決此問題:
generate_output \
2> >(tee <&0 >(cat > err.log)) \
1> >(tee <&0 >(cat > out.log))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/355075.html
標籤:猛击
上一篇:洗掉串列中不存在的目錄和子目錄
