É muito mais fácil visualizar as coisas se você pensar sobre o que realmente está acontecendo com "redirecionamentos" e "pipes". Redirecionamentos e canais no bash fazem uma coisa: modifique para onde os descritores de arquivo de processo 0, 1 e 2 apontam para (consulte / proc / [pid] / fd / *).
Quando um tubo ou "|" Se o operador estiver presente na linha de comando, a primeira coisa a acontecer é que o bash cria um fifo e aponta o FD 1 do comando do lado esquerdo para este fifo e aponta o FD 0 do comando do lado direito para o mesmo fifo.
Em seguida, os operadores de redirecionamento de cada lado são avaliados da esquerda para a direita e as configurações atuais são usadas sempre que ocorre a duplicação do descritor. Isso é importante porque, desde que o tubo foi configurado primeiro, o FD1 (lado esquerdo) e o FD0 (lado direito) já foram alterados do que normalmente poderiam ter sido, e qualquer duplicação destes refletirá esse fato.
Portanto, quando você digita algo como o seguinte:
command 2>&1 >/dev/null | grep 'something'
Aqui está o que acontece, em ordem:
- um tubo (fifo) é criado. "comando FD1" está apontado para este canal. "grep FD0" também é apontado para este canal
- "comando FD2" é apontado para onde "comando FD1" aponta atualmente (o canal)
- "comando FD1" está apontado para / dev / null
Portanto, toda saída que esse "comando" grava em seu FD 2 (stderr) segue para o canal e é lida por "grep" no outro lado. Toda saída que "comando" grava em seu FD 1 (stdout) chega a / dev / null.
Em vez disso, você executa o seguinte:
command >/dev/null 2>&1 | grep 'something'
Aqui está o que acontece:
- um pipe é criado e "command FD 1" e "grep FD 0" são apontados para ele
- "comando FD 1" está apontado para / dev / null
- "comando FD 2" é apontado para onde o FD 1 aponta atualmente (/ dev / null)
Portanto, todos os stdout e stderr do "comando" vão para / dev / null. Nada vai para o canal e, assim, o "grep" será fechado sem exibir nada na tela.
Observe também que os redirecionamentos (descritores de arquivo) podem ser somente leitura (<), somente gravação (>) ou leitura e gravação (<>).
Uma nota final. Se um programa grava algo em FD1 ou FD2, depende inteiramente do programador. As boas práticas de programação determinam que as mensagens de erro devem ir para o FD 2 e a saída normal para o FD 1, mas muitas vezes você encontrará uma programação desleixada que mistura os dois ou ignora a convenção.