Em bash
, se você fizer isso:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3887 16480 16480 pts/29 00:00:00 bash
3888 3888 16480 pts/29 00:00:00 cat
3889 16480 16480 pts/29 00:00:00 ps
16480 16480 16480 pts/29 00:00:00 bash
Em zsh
:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3935 3935 16480 pts/29 00:00:00 ps
3936 3936 16480 pts/29 00:00:00 cat
16480 16480 16480 pts/29 00:00:00 zsh
Em ksh93
:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3946 16480 16480 pts/29 00:00:00 ps
3947 3947 16480 pts/29 00:00:00 cat
16480 16480 16480 pts/29 00:00:00 ksh
Em todos os 3 shells, o processo ps
está em um grupo de processos diferente do grupo cat
, que é o grupo de processos em primeiro plano do terminal. zsh
, pelo menos, é bom o suficiente para redirecionar o stdin para /dev/null
se fosse um tty para evitar problemas com isso, como muitos shells fazem para que os comandos sejam executados em segundo plano.
Seu comando funcionará bem se stdin não for um terminal, mas aqui, como cat
não está no grupo de processos em primeiro plano do terminal, a leitura do terminal significa que ele receberá um sinal SIGTTIN
que causaria para ser suspenso. E isso não é tratado graciosamente aqui. No seu caso, parece que SIGTTIN
está sendo ignorado ou bloqueado para que você receba um erro de EIO (obtido ao tentar ler a partir do terminal de controle quando não está em seu grupo de processos em primeiro plano e ignorar / bloquear SIGTTIN
).
Em
(head <(cat <&3)) 3<&0
no entanto, estamos iniciando um sub-shell em primeiro plano, e todos os processos nele acabam no mesmo grupo de processos, portanto, podem ler o terminal. Com o redirecionamento explícito, com zsh
, estamos ignorando o redirecionamento de zsh
de /dev/null
. Com outras conchas,
(head <(cat))
também funcionaria.