Bash為什麼
為什麼... |當
… > >(sed ’s/^/stdout: /’) 不列印時,sed 's/^/stdout: /'
在空標準輸入上列印?
我試圖了解是什麼導致了我認為在功能上等效的這兩個構造的差異:
$ ( echo foo >&2 ) 2> >(sed 's/^/stderr: /') | sed 's/^/stdout: /' stdout: stderr: foo $ ( echo foo >&2 ) 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /') stderr: foo
編輯:如果我理解 user1133275 正確,他建議
>(sed 's/^/stdout: /')
不要執行,除非子外殼( echo foo >&2 )
輸出到標準輸出。但是,這將意味著以下內容:$ ( echo foo >&2 ) 2> >(sed 's/^/stderr: /') > >(echo baz) baz stderr: foo
不應該顯示
baz
。編輯 2:也許也很有趣, sed 不會
stdout:
在空輸入上輸出,即使是通過管道傳輸的:$ sed 's/^/stdout: /' < /dev/null $ printf "" | sed 's/^/stdout: /' $
你的第一個命令,
( echo foo >&2 ) 2> >(sed 's/^/stderr: /') | sed 's/^/stdout: /'
以簡化形式(使用臨時文件保存由 生成的數據
echo
):{ echo foo 2>file >&2; sed 's/^/stderr: /' file; } | sed 's/^/stdout: /'
即,第一個
sed
讀取從標準錯誤產生的內容echo
並寫入標準輸出,第二個sed
讀取並修改它。你的第二個命令,
( echo foo >&2 ) 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /')
以簡化的形式,
echo foo 2>file >&2; sed 's/^/stderr: /' file; sed 's/^/stdout: /' </dev/null
在這裡,
sed
獲得標準錯誤輸出的那個產生輸出,而另一個sed
獲得標準輸出輸出(什麼都沒有)的那個不產生任何輸出(因為它沒有得到任何輸入並且因為它沒有插入或附加任何數據) .另一種表述方式:
第一個命令:
( echo foo >&2 ) 2>file sed 's/^/stderr: /' file | sed 's/^/stdout: /'
第二條命令:
( echo foo >&2 ) 2>file >otherfile sed 's/^/stderr: /' file sed 's/^/stdout: /' otherfile
簡而言之,第二
sed
個命令中的第二個從不讀取任何內容。特別是,它不像第sed
一個命令那樣從第一個命令中讀取輸出。使用極其簡化的符號,第一個命令類似於
utility-writing-to-stderr 2> >(something1) | something2
where
something1
寫入標準輸出,由something2
.第二個命令,使用相同的符號,
utility-writing-to-stderr 2> >(something1) >(something2)
即
something1
,something2
甚至沒有相互連接,並且something2
無法以任何方式讀取something1
正在產生的內容。此外,由於utility-writing-to-stderr
不會在其標準輸出流上產生任何內容,something2
因此不會從其標準輸入中讀取任何內容。