Em zsh, diferença entre cat (cat) vs cat | gato vs gato = (gato)?

18

Eu esperava que cat <(cat) e cat | cat fizessem o mesmo: copiar linhas de stdin para stdout. Meu entendimento era que ambos executariam um cat em um subshell, redirecionariam o stdout do subshell cat para um pipe nomeado temporário e executariam outro cat no shell atual com seu stdin redirecionado para o pipe. / p>

Em vez disso, cat <(cat) me permite digitar no meu terminal, mas nenhuma das linhas de entrada é copiada e ^D não sinaliza EOF ; cat | cat funciona como esperado.

Como experimento adicional, verifiquei se cat =(cat) tem dificuldades semelhantes às de cat <(cat) , mas funciona como eu esperava: todos os stdin até ^D são copiados para stdout de uma só vez.

Alguém pode me ajudar a entender o que zsh está fazendo sob o capô?

    
por Alan O'Donnell 27.07.2012 / 03:15

1 resposta

23
  1. a | b conecta STDOUT de a e STDIN de b usando apenas dup/dup2 . Ambos os comandos são executados em paralelo.

  2. a =(b) substitui o argumento por a por um nome de arquivo temporário. b será executado antes de a , pois o arquivo temporário precisa ser criado antes de ser passado para a

  3. a <(b) substitui o argumento por a por um canal nomeado. a e b são executados em paralelo. Agora é aí que fica um pouco complicado:

    b está em segundo plano e não consegue ler o terminal. Você mesmo pode testá-lo usando strace -p $PID para anexar ao seu segundo processo de gato para ver o processo.

    a , enquanto isso, tenta ler o pipe nomeado, mas não consegue ler nada, já que b não pode ler.

    • Isso significa que você basicamente tem um deadlock no qual a tenta ler b , mas b não pode ler STDIN e não pode gravar em a

Mais informações sobre o processo em segundo plano e o terminal de homem bash :

To facilitate the implementation of the user interface to job control, the operating system maintains the notion of a current terminal process group ID. Members of this process group (processes whose process group ID is equal to the current terminal process group ID) receive keyboard-generated signals such as SIGINT. These processes are said to be in the foreground. Background processes are those whose process group ID differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or, if the user so specifies with stty tostop, write to the terminal. Background processes which attempt to read from (write to when stty tostop is in effect) the terminal are sent a SIGTTIN (SIGTTOU) signal by the kernel's terminal driver, which, unless caught, suspends the process.

    
por 27.07.2012 / 03:49