Efeito no operador de pipe shell em stdin, stdout e stderr

1

Quando eu crio um pipe usando o shell, por exemplo:

ls | cat

O que eu sei com certeza é que stdin para cat será o stdout para ls (ou seja, tudo ls grava em seu stdout , cat irá lê-lo por meio de stdin ).

Agora tenho duas perguntas:

  1. O stdin para ls será o stdout para cat ?
  2. O stderr para ls e cat foi afetado pelo operador pipe ou ainda será o valor stderr herdado do shell?
por user8240761 02.11.2017 / 18:11

1 resposta

5

Tecnicamente, em ls | cat

  • o stdout de ls (seu fd 1) será o final de gravação de um pipe (ou socketpair com ksh93 em alguns sistemas).
  • o stdin de cat (seu fd 0) será o final de leitura desse mesmo canal
  • os dois comandos serão executados simultaneamente (são iniciados ao mesmo tempo em processos separados)
  • stdin de ls não é afetado (pergunta 1)
  • stdout de cat não é afetado (pergunta 1)
  • stderr (fd 2) de ls ou cat não são afetados (pergunta 2).

Para que o stderr de ls também vá para a extremidade de gravação do pipe (assim, cat pode lê-lo de seu stdin na outra extremidade do pipe), você pode fazer:

ls 2>&1 | cat

O que diz: "make fd 2 aponta para o mesmo recurso que no fd 1 (aqui o pipe)"

Com csh , tcsh , zsh ou bash 4.0 ou acima, você também pode escrevê-lo:

ls |& cat

Em sistemas nos quais os tubos são bidirecionais, você pode fazer:

ls <&1 | cat >&0

para que o stdout de cat seja realimentado para ls através do mesmo pipe, mas na direção inversa, mas isso seria inútil, pois ls nunca lê seu stdin.

No Linux, onde os pipes não são bidirecionais, esse comando daria um erro.

    
por 02.11.2017 / 18:26