Por que o stdout do primeiro comando neste canal não está sendo processado?

Por que o stdout do primeiro comando neste canal não está sendo processado?

Estou tentando escrever um comando que possa simultaneamente (i) ler stdin e (ii) ler um pipe. Este conceito básico funciona em zsh, mas não em bash. A sessão a seguir ilustra a diferença de comportamento dos dois shells:

$ 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

Posso ver que os comandos acima fornecem catduas fontes de stdin (o pipe e o redirecionamento), então talvez seja ambíguo como isso deve ser tratado. zshparece concatenar os dois fluxos de entrada, com a entrada canalizada vindo consistentemente primeiro. bashparece simplesmente descartar a entrada canalizada.

Minhas perguntas são:

  1. Por que as duas conchas se comportam de maneira diferente?
  2. Existe alguma maneira de forçar basha se comportar como zsh?

Responder1

Como você notou, oMULTIOSopção de shellin zshé o que torna isso possível. Não há nenhum recurso integrado semelhante no bashshell.

Em bash, você obteria o mesmo comportamento (para este exemplo específico; consulteComentário do tio Billy abaixo) de

echo foo | { cat; cat bar; }

ou

echo foo | cat - bar

Ambos os lados direitos primeiro leem suas entradas padrão antes de ler bar.

Responder2

Passei mais algum tempo olhando para isso e descobri que o comportamento de zshé devido aoMULTIOSopção, que está habilitado por padrão. bashnão parece ter uma opção comparável, então esse comportamento é específico para zsh.

informação relacionada