Почему stdout из первой команды в этом канале не обрабатывается?

Почему stdout из первой команды в этом канале не обрабатывается?

Я пытаюсь написать команду, которая может одновременно (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похоже, просто отбрасывает конвейерный ввод.

У меня есть вопросы:

  1. Почему две оболочки ведут себя по-разному?
  2. Есть ли способ заставить себя bashвести себя как zsh?

решение1

Как вы заметили,MULTIOSвариант оболочкив zshтом, что делает это возможным. В оболочке нет подобного встроенного оборудования bash.

В bash, вы получите то же самое поведение (для этого конкретного примера; см.Комментарий дяди Билли ниже) от

echo foo | { cat; cat bar; }

или

echo foo | cat - bar

Обе эти правые части сначала считывают свои стандартные входные данные, а затем считывают bar.

решение2

Я потратил еще немного времени, разглядывая это, и обнаружил, что поведение zshсвязано сMULTIOSвариант, который включен по умолчанию. bashпохоже, не имеет сопоставимой опции, поэтому такое поведение характерно для zsh.

Связанный контент