回答:
これはシェルに依存しており、文書化されていません。ksh及びbash、最初のケースでは、foo同様の標準入力を共有しますbar。彼らはの出力のために戦うでしょうecho。
たとえば、
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
の出力pasteからテキストの他のすべてのブロックを読み取り、他のブロックを読み取る証拠が表示されます。seqtr
でzsh、それは外側の標準入力を取得します(それが端末であり、シェルがインタラクティブでない場合は、その場合にリダイレクトされます/dev/null)。ksh(元々)、zshおよびbashプロセス置換AFAIKをサポートする唯一のBourne風のシェルです。
ではecho "bla" | bar < <(foo)、barのstdinはの出力によって供給されるパイプになることに注意してくださいfoo。それは明確に定義された振る舞いです。その場合、fooのstdinは、およびのechoすべてで供給されるパイプであるように見えます。kshzshbash
3つのシェルすべてで一貫した動作を行い、文書化されていないため動作が変更される可能性があるため、将来を見越したい場合は、次のように記述します。
echo bla | { bar <(foo); }
確かにfooの標準入力からもパイプであるecho(あなたががそれをやりたいと思いますなぜ私が見ることができません)。または:
echo bla | bar <(foo < /dev/null)
確認するにfooは、からのパイプから読み取らないでくださいecho。または:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
。のfoo現在のバージョンのように外側のstdin を持っていますzsh。
echo "bla" | foo | bar:の出力echo "bla"はにリダイレクトされfoo、その出力はにリダイレクトされbarます。
echo "bla" | bar <(foo):の出力をecho "bla"toにパイプしますbar。しかしbar、引数付きで実行されます。引数は、出力fooが送信されるファイル記述子へのパスです。この引数は、の出力を含むファイルのように動作しますfoo。それで、それは同じではありません。
echo "bla" | bar < <(foo):の出力をecho "bla"送信する必要がbarあり、ステートメント全体が最初のものと同等であると仮定する場合があります。しかし、それは正しくありません。次のことが起こります。入力リダイレクト<はパイプ(|)の後に実行されるため、上書きされます。だからecho "bla"バーにパイプされていません。代わりに、の出力はfooへの標準入力としてリダイレクトされますbar。これをクリアするには、次のコマンドと出力を参照してください。
$ echo "bla" | cat < <(echo "foo")
foo
ご覧のとおり、にecho "bla"置き換えられecho "foo"ます。
次のコマンドを参照してください。
$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo
にecho "bar"パイプされawk、stdinを読み取りand foo、出力に文字列を追加します。この出力はにパイプされcatます。
awk「「バー」と表示されているという事実は定義された動作ですか?」
cmd1 < <(cmd2)と同じように動作しcmd2 | cmd1ます。
cmd1 | cmd2 | cmd3と同じですcmd1 | cmd3 < <(cmd2)