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