Redirecionamento: stdin, stdout, stderr e o operador >

1. Introdução aos Fluxos Padrão (Streams)

No Bash, todo processo em execução possui três fluxos de dados fundamentais, conhecidos como descritores de arquivo. O shell gerencia automaticamente esses fluxos para permitir a comunicação entre comandos, arquivos e o terminal.

stdin (Standard Input) — descritor 0 — é o fluxo de entrada padrão. Por padrão, recebe dados do teclado, mas pode ser redirecionado para ler de arquivos ou da saída de outros comandos.

stdout (Standard Output) — descritor 1 — é o fluxo de saída padrão. Exibe resultados normais de comandos diretamente no terminal.

stderr (Standard Error) — descritor 2 — é o fluxo de saída de erros. Mensagens de erro e diagnósticos são enviados separadamente para este fluxo, permitindo que você trate saídas normais e erros de forma independente.

Por padrão, tanto stdout quanto stderr são exibidos no terminal, mas podem ser redirecionados individualmente para arquivos ou outros destinos.

2. Redirecionamento de Saída com > e >>

O operador > redireciona stdout para um arquivo, sobrescrevendo seu conteúdo existente. Se o arquivo não existir, ele é criado automaticamente.

echo "Este é um exemplo" > arquivo.txt
cat arquivo.txt
# Saída: Este é um exemplo

Para anexar dados ao final de um arquivo sem destruir o conteúdo anterior, utilize >>:

echo "Segunda linha" >> arquivo.txt
cat arquivo.txt
# Saída:
# Este é um exemplo
# Segunda linha

Cuidado: O operador > sobrescreve o arquivo silenciosamente. Um comando como > arquivo.txt (sem comando antes) cria um arquivo vazio, destruindo qualquer conteúdo anterior. Sempre verifique se não há dados importantes antes de usar >.

3. Redirecionamento de Entrada com <

O operador < redireciona o conteúdo de um arquivo como entrada para um comando, substituindo a entrada padrão do teclado.

sort < lista.txt
# Lê o conteúdo de lista.txt e o ordena

Exemplo prático com contagem de linhas:

wc -l < dados.log
# Retorna apenas o número de linhas, sem o nome do arquivo

É possível combinar redirecionamento de entrada e saída em um único comando:

sort < dados_entrada.txt > dados_ordenados.txt
# Lê de dados_entrada.txt, ordena e escreve em dados_ordenados.txt

4. Redirecionamento de Erros (stderr)

Para redirecionar stderr separadamente, utilize 2> (sobrescrevendo) ou 2>> (anexando):

comando_inexistente 2> erros.log
# Mensagens de erro são salvas em erros.log
cat erros.log
# bash: comando_inexistente: command not found

A diferença prática entre stdout e stderr fica evidente quando você deseja processar apenas saídas normais ou apenas erros:

find / -name "*.conf" > resultados.txt 2> erros.txt
# Resultados vão para resultados.txt, erros de permissão para erros.txt

5. Redirecionamento Simultâneo e Descritores

Para redirecionar tanto stdout quanto stderr para o mesmo destino, existem duas sintaxes equivalentes:

comando &> arquivo.txt
# Redireciona ambos os fluxos para arquivo.txt (forma abreviada)
comando > arquivo.txt 2>&1
# Redireciona stdout para arquivo.txt, depois duplica stderr para seguir stdout

A ordem dos redirecionamentos é crucial. Compare os exemplos abaixo:

# Correto: stderr é duplicado para o stdout já redirecionado
comando > saida.txt 2>&1
# Ambos os fluxos vão para saida.txt
# Incorreto: stdout é redirecionado, mas stderr foi duplicado para o stdout original
comando 2>&1 > saida.txt
# Apenas stdout vai para saida.txt; stderr continua no terminal

A regra é simples: primeiro redirecione o destino (stdout), depois duplique o outro fluxo (stderr).

6. Técnicas Avançadas com /dev/null e Here Documents

Descartando saídas indesejadas: O dispositivo especial /dev/null funciona como um "buraco negro" que descarta todo dado recebido.

comando_ruidoso > /dev/null 2>&1
# Descarta completamente stdout e stderr

Here Documents (<<): Permitem fornecer múltiplas linhas de entrada diretamente no script, até encontrar um delimitador:

cat << FIM
Linha 1 do documento
Linha 2 do documento
FIM

Here Strings (<<<): Redirecionam uma única string como entrada para um comando:

grep "erro" <<< "linha com erro encontrado"
# Útil para testar expressões regulares rapidamente

7. Boas Práticas e Armadilhas Comuns

Verifique permissões: Antes de redirecionar para um arquivo, confirme se você tem permissão de escrita no diretório. Um redirecionamento falho pode interromper seu script.

test -w /etc && echo "ok" > /etc/teste.txt || echo "Sem permissão"

Diferença entre > e |: O pipe (|) conecta stdout de um comando ao stdin do próximo, enquanto > redireciona para um arquivo. Eles não são intercambiáveis.

# Pipe: saída de um comando vira entrada de outro
ls | grep ".txt"

# Redirecionamento: saída vai para arquivo
ls > listagem.txt

Depuração com set -x: Ative o modo de rastreamento para visualizar como o shell interpreta os redirecionamentos:

set -x
comando > arquivo.txt 2>&1
set +x

Isso exibirá cada expansão e redirecionamento, ajudando a identificar problemas de ordem ou sintaxe.

Referências