Bash

為什麼... |當 … > >(sed ’s/^/stdout: /’) 不列印時,sed 's/^/stdout: /' 在空標準輸入上列印?

  • January 19, 2019

我試圖了解是什麼導致了我認為在功能上等效的這兩個構造的差異:

$ ( 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

wheresomething1寫入標準輸出,由something2.

第二個命令,使用相同的符號,

utility-writing-to-stderr 2> >(something1) >(something2)

something1something2甚至沒有相互連接,並且something2無法以任何方式讀取something1正在產生的內容。此外,由於utility-writing-to-stderr不會在其標準輸出流上產生任何內容,something2因此不會從其標準輸入中讀取任何內容。

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