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
lsnão é afetado (pergunta 1) - stdout de
catnão é afetado (pergunta 1) - stderr (fd 2) de
lsoucatnã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.