![このパイプの最初のコマンドからの stdout が処理されないのはなぜですか?](https://rvso.com/image/170639/%E3%81%93%E3%81%AE%E3%83%91%E3%82%A4%E3%83%97%E3%81%AE%E6%9C%80%E5%88%9D%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%20stdout%20%E3%81%8C%E5%87%A6%E7%90%86%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A7%E3%81%99%E3%81%8B%3F.png)
私は、(i) stdin からの読み取りと (ii) パイプからの読み取りを同時に実行できるコマンドを作成しようとしています。この基本概念は では機能しますzsh
が、 では機能しませんbash
。次のセッションは、2 つのシェルの動作の違いを示しています。
$ echo bar > bar
$ zsh -f
zsh-5.8$ echo foo | cat < bar
foo
bar
zsh-5.8$ exit
$ bash --noprofile --norc
bash-5.0$ echo foo | cat < bar
bar
上記のコマンドはcat
stdin の 2 つのソース (パイプとリダイレクト) を提供するため、これをどのように処理するかがあいまいである可能性があります。 は、 zsh
2 つの入力ストリームを連結しているように見えますが、パイプされた入力は常に最初に来ます。 は、 bash
パイプされた入力を単にドロップしているように見えます。
私の質問は次のとおりです:
- なぜ 2 つのシェルの動作が異なるのでしょうか?
bash
のように動作するように強制する方法はありますかzsh
?
答え1
ご存知のとおり、MULTIOS
シェルオプションがzsh
これを可能にします。シェルには同様の組み込み機能はありませんbash
。
ではbash
、同じ動作になります(この特定の例では、ビリーおじさんのコメントは以下) から
echo foo | { cat; cat bar; }
または
echo foo | cat - bar
これら右側の両辺は、 を読み取る前にまず標準入力を読み取りますbar
。
答え2
私はもう少し時間をかけてこれを調べ、の挙動zsh
はMULTIOS
オプションはデフォルトで有効になっています。 には bash
同等のオプションがないようですので、この動作は に固有のものですzsh
。