![Почему stdout из первой команды в этом канале не обрабатывается?](https://rvso.com/image/170639/%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83%20stdout%20%D0%B8%D0%B7%20%D0%BF%D0%B5%D1%80%D0%B2%D0%BE%D0%B9%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%8B%20%D0%B2%20%D1%8D%D1%82%D0%BE%D0%BC%20%D0%BA%D0%B0%D0%BD%D0%B0%D0%BB%D0%B5%20%D0%BD%D0%B5%20%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%B0%D1%82%D1%8B%D0%B2%D0%B0%D0%B5%D1%82%D1%81%D1%8F%3F.png)
Я пытаюсь написать команду, которая может одновременно (i) читать из stdin и (ii) читать из pipe. Эта базовая концепция работает в zsh
, но не в bash
. Следующий сеанс иллюстрирует разницу в поведении для двух оболочек:
$ 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 (канал и перенаправление), поэтому, возможно, неоднозначно, как это следует обрабатывать. zsh
похоже, объединяет два входных потока, причем конвейерный ввод постоянно идет первым. bash
похоже, просто отбрасывает конвейерный ввод.
У меня есть вопросы:
- Почему две оболочки ведут себя по-разному?
- Есть ли способ заставить себя
bash
вести себя какzsh
?
решение1
Как вы заметили,MULTIOS
вариант оболочкив zsh
том, что делает это возможным. В оболочке нет подобного встроенного оборудования bash
.
В bash
, вы получите то же самое поведение (для этого конкретного примера; см.Комментарий дяди Билли ниже) от
echo foo | { cat; cat bar; }
или
echo foo | cat - bar
Обе эти правые части сначала считывают свои стандартные входные данные, а затем считывают bar
.
решение2
Я потратил еще немного времени, разглядывая это, и обнаружил, что поведение zsh
связано сMULTIOS
вариант, который включен по умолчанию. bash
похоже, не имеет сопоставимой опции, поэтому такое поведение характерно для zsh
.