回答:
これはシェルに依存しており、文書化されていません。ksh
及びbash
、最初のケースでは、foo
同様の標準入力を共有しますbar
。彼らはの出力のために戦うでしょうecho
。
たとえば、
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
の出力paste
からテキストの他のすべてのブロックを読み取り、他のブロックを読み取る証拠が表示されます。seq
tr
でzsh
、それは外側の標準入力を取得します(それが端末であり、シェルがインタラクティブでない場合は、その場合にリダイレクトされます/dev/null
)。ksh
(元々)、zsh
およびbash
プロセス置換AFAIKをサポートする唯一のBourne風のシェルです。
ではecho "bla" | bar < <(foo)
、bar
のstdinはの出力によって供給されるパイプになることに注意してくださいfoo
。それは明確に定義された振る舞いです。その場合、foo
のstdinは、およびのecho
すべてで供給されるパイプであるように見えます。ksh
zsh
bash
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)