`...>>(sed's/^/stdout: /')` は印刷されません。 sed 's / ^ / stdout:/ 'が空の標準入力に印刷されるのはなぜですか?

`...>>(sed's/^/stdout: /')` は印刷されません。 sed 's / ^ / stdout:/ 'が空の標準入力に印刷されるのはなぜですか?

私は機能的に同じと思われる2つの構造の違いを引き起こす原因を理解しようとしています。

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

stdout:編集2:おそらく興味深いことに、sedはパイピング中に空の入力に対して出力しません。

$ sed 's/^/stdout: /' < /dev/null
$ printf "" | sed 's/^/stdout: /'
$

ベストアンサー1

最初のコマンド、

( 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それを標準出力に書き込み、2番目のものはsedそれを読み取って修正します。

2番目のコマンドは

( 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、stderrを取得することは出力を生成しますが、stderr(何もなし)を取得する他はsed出力を生成しません(入力が得られず、データが挿入または追加されないため)。

他の表現として:

最初のコマンド:

( echo foo >&2 ) 2>file
sed 's/^/stderr: /' file | sed 's/^/stdout: /'

2番目のコマンド:

( echo foo >&2 ) 2>file >otherfile
sed 's/^/stderr: /' file
sed 's/^/stdout: /' otherfile

つまり、sed2つのコマンドのうち2番目のコマンドは何も読みません。特に、最初のコマンドと同様に、最初のコマンドの出力を読み取ることはありませんsed


非常に単純化された表記法を使用すると、最初のコマンドは次のようになります。

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

これはsomething1標準出力に書き込まれますsomething2

2番目のコマンドは同じ表記法を使用します。

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

つまり、互いに連結されていsomething1なくても何らかの方法で生成される内容を読み取ることができません。さらに、標準出力ストリームでは何も生成されないため、標準入力から何も読み取れません。something2something2something1utility-writing-to-stderrsomething2

おすすめ記事