Redirecionamento de E/S
Esta aula explica os conceitos fundamentais de redirecionamento de entrada e saída no shell Linux/Bash, abordando os fluxos padrão stdin, stdout e stderr, operadores como >, >>, 2> e &>, e o dispositivo especial /dev/null. O conteúdo inclui exemplos práticos e boas práticas para manipular a saída de comandos de forma eficiente.
Redirecionamento de E/S (Entrada/Saída) é um dos recursos mais poderosos do shell Linux/Bash. Ele permite controlar de onde um comando lê dados (entrada) e para onde ele escreve sua saída (resultados e erros). Compreender esse mecanismo é essencial para criar scripts eficientes, automatizar tarefas e lidar com logs e mensagens de erro de forma granular.
No Linux, tudo é tratado como arquivo, e os fluxos de E/S são identificados por números chamados descritores de arquivo. Os três principais são: 0 (entrada padrão), 1 (saída padrão) e 2 (saída de erro padrão). O shell oferece operadores especiais para redirecionar esses fluxos para arquivos, dispositivos ou até mesmo para outros comandos.
stdin, stdout, stderr
Cada processo no Linux possui três fluxos de E/S padrão. O stdin (descritor 0) é a entrada padrão, normalmente associada ao teclado. O stdout (descritor 1) é a saída padrão, onde os resultados normais do comando são enviados, geralmente para o terminal. O stderr (descritor 2) é a saída de erro padrão, usada para mensagens de erro e diagnóstico, também por padrão direcionada ao terminal.
Essa separação permite que você redirecione apenas a saída normal para um arquivo, enquanto os erros continuam sendo exibidos na tela, ou vice-versa. Por exemplo, ao executar um comando que pode gerar erros, você pode salvar os erros em um arquivo separado para análise posterior, sem misturá-los com a saída normal.
# Exemplo: listar arquivos e redirecionar stdout para um arquivo
ls -l > lista.txt
# O stdout (lista) vai para o arquivo; erros (ex: diretório inexistente) vão para o terminal
# Redirecionar stderr para um arquivo
ls /diretorio_inexistente 2> erros.txt
> e >>
O operador > redireciona a saída padrão (stdout) para um arquivo, sobrescrevendo o conteúdo existente. Se o arquivo não existir, ele é criado. Já o operador >> redireciona a saída padrão para um arquivo, mas adiciona ao final do arquivo (append), preservando o conteúdo anterior.
Esses operadores são amplamente usados para salvar resultados de comandos, criar logs e gerar relatórios. É importante lembrar que, por padrão, eles atuam apenas sobre o stdout. Para redirecionar stderr, é necessário especificar o descritor (2> ou 2>>).
# Sobrescrever arquivo com a saída do comando
echo "Novo conteúdo" > arquivo.txt
# Adicionar ao final do arquivo
echo "Mais conteúdo" >> arquivo.txt
# Exemplo com data: adicionar timestamp a um log
date >> log.txt
2> e &>
O operador 2> redireciona o stderr (descritor 2) para um arquivo, sobrescrevendo. Para adicionar (append) ao arquivo, use 2>>. Já o operador &> redireciona tanto stdout quanto stderr para um mesmo arquivo (ou dispositivo). É uma forma concisa de mesclar os dois fluxos.
Existem também variações como > arquivo 2>&1, que primeiro redireciona stdout para o arquivo e depois faz o stderr apontar para o mesmo destino de stdout. O &> é um atalho para isso no Bash. Dominar esses redirecionamentos é crucial para lidar com erros em scripts e para criar logs completos.
# Redirecionar apenas erros para um arquivo
comando_que_pode_falhar 2> erros.log
# Redirecionar stdout e stderr para o mesmo arquivo (sobrescrevendo)
comando &> tudo.log
# Equivalente usando descritores
comando > tudo.log 2>&1
# Adicionar ambos ao final de um arquivo
comando >> tudo.log 2>&1
/dev/null
/dev/null é um dispositivo especial no Linux que funciona como um "buraco negro": tudo que é enviado para ele é descartado. É útil quando você não quer ver a saída de um comando, nem erros, e não deseja armazená-los em arquivo. Por exemplo, para silenciar completamente um comando, redirecione stdout e stderr para /dev/null.
Outro uso comum é em scripts que verificam a existência de um arquivo: você pode redirecionar erros para /dev/null para evitar mensagens indesejadas. Também é usado para descartar saídas de comandos que você só quer executar pelo efeito colateral (como criar diretórios).
# Descartar toda a saída (stdout e stderr)
comando &> /dev/null
# Verificar se um arquivo existe sem exibir erros
if ls /arquivo_inexistente 2> /dev/null; then
echo "Arquivo existe"
else
echo "Arquivo não existe"
fi
# Descartar apenas a saída normal, mas ver erros
comando > /dev/null
Boas Práticas e Observações Finais
Ao usar redirecionamento, lembre-se de que a ordem importa. Por exemplo, 2>&1 > arquivo redireciona stderr para o stdout atual (que ainda é o terminal), e depois redireciona stdout para o arquivo, então os erros ainda vão para o terminal. A forma correta é > arquivo 2>&1 ou usar &>.
Outra dica: em scripts, é comum usar exec para redirecionar todos os comandos subsequentes. Por exemplo, exec &> log.txt redireciona toda a saída do script para o arquivo. Isso simplifica o código quando muitos comandos precisam ter a saída capturada.
Por fim, lembre-se de que o redirecionamento também pode ser usado com pipes (|) para conectar a saída de um comando à entrada de outro. Essa combinação é a base do pipeline no Unix.
Referências
- GNU Bash Manual: Redirections
- Advanced Bash-Scripting Guide: I/O Redirection
- Linuxize: Bash Redirect stderr and stdout
- nixCraft: Redirecting stderr to stdout
- Wikipedia: /dev/null
- GNU Bash Manual: Shell Operation (File Descriptors)
Exercícios
-
Crie um comando que liste o conteúdo do diretório atual e salve a saída normal em um arquivo chamado
saida.txt, mas os erros (por exemplo, se houver problemas de permissão) devem ser mostrados no terminal.✓ Resposta:ls -l > saida.txtO stdout é redirecionado para o arquivo; stderr (erros) permanece no terminal.
-
Redirecione tanto stdout quanto stderr de um comando (por exemplo,
ls /etc/passwd /etc/arquivo_inexistente) para o mesmo arquivotudo.log, sobrescrevendo o conteúdo anterior.✓ Resposta:ls /etc/passwd /etc/arquivo_inexistente &> tudo.logOu:
ls /etc/passwd /etc/arquivo_inexistente > tudo.log 2>&1 -
Adicione a data e hora atuais ao final de um arquivo de log chamado
historico.log, sem sobrescrever o conteúdo existente.✓ Resposta:date >> historico.log -
Execute um comando que pode gerar erros (ex:
rm /arquivo_inexistente) e descarte completamente qualquer saída (stdout e stderr), sem criar nenhum arquivo.✓ Resposta:rm /arquivo_inexistente &> /dev/null -
Escreva um comando que liste todos os arquivos .txt no diretório atual, redirecione apenas os erros (se houver) para um arquivo
erros.txt, e mostre a saída normal no terminal.✓ Resposta:ls *.txt 2> erros.txtO stdout (lista de arquivos .txt) vai para o terminal; stderr (se não houver arquivos .txt ou problemas de permissão) vai para erros.txt.