Substituição de processo e cat: não é possível ler stdin

2

A substituição do processo <(cat) não funciona. Por quê?

head <(cat) 
cat: -: Input/output error

Eu posso usar um descritor de arquivo extra, mas não entendo por que o acima não funciona.

# Using file descriptor 3 to reroute the input
(head <(cat <&3)) 3<&0
    
por Georges Dupéron 20.11.2015 / 11:13

1 resposta

4

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.

    
por 20.11.2015 / 11:59