次の行は明らかです。
echo "bla" | foo | bar
しかし、私の下の人々もそうしますか?
echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)
標準入力から「bla」を読むのはなぜですかfoo
?bar
もちろん、コーディングして確認することはできますが、定義された動作であるか、依存してはいけない機能を活用しているかどうかはわかりません。
答え1
これはシェルによって異なり、AFAICS に文書化されていません。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
端末からcmd &
)。ksh
(原産地)プロセスの交換をサポートする唯一のBourne様シェルですzsh
。bash
では、stdinがの出力から提供されるパイプであることにecho "bla" | bar < <(foo)
注意してください。これは明確に定義された動作です。この場合、stdinがすべてであるように見え、パイプも提供されます。bar
foo
foo
echo
ksh
zsh
bash
3つのシェルすべてで一貫した動作が必要になり、動作が文書化されずに変更される可能性があるため、将来も備えたい場合は、次のように作成します。
echo bla | { bar <(foo); }
確かにfoo
stdinもパイプから出てきますecho
(しかし、なぜそうしたいのかわかりません)。または:
echo bla | bar <(foo < /dev/null)
foo
確認してくださいいいえパイプから読みますecho
。または:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
foo
の現在のバージョンと同じMakeのstdin外部標準入力ですzsh
。
答え2
echo "bla" | foo | bar
:の出力はecho "bla"
にリダイレクトされfoo
、その出力はにリダイレクトされますbar
。
echo "bla" | bar <(foo)
:出力echo "bla"
を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
。