Linux: Streams Padrão e Redirecionamento
O Linux trata cada programa como um "filtro" — recebendo entrada de algum lugar, processando-a e gerando resultados. Os canais de entrada e saída são os streams padrão.
📋 Pré-requisitos: Você deve primeiro concluir
1. O Que Você Vai Aprender
- Conceitos de entrada, saída e erro padrão
- A diferença entre
>e>> 2>para redirecionar erros&>para redirecionar ambos os streams- Aplicações de
/dev/null
2. A História de uma Tela Cheia de Erros
(1) O Problema: Saída Mista Dificulta Encontrar o Que Você Precisa
Alex executou apt update, e mensagens de sucesso misturadas com mensagens de erro vermelhas passaram pela tela. Ele queria salvar apenas os resultados bem-sucedidos e ver os erros separadamente.
(2) Separando Saída com Redirecionamento
Bob ensinou-lhe a usar redirecionamento:
# Salvar mensagens de sucesso em success.log, erros em error.log
sudo apt update > success.log 2> error.log
# Ver os erros
cat error.log
(3) O Benefício: Controle Preciso de Saída
Alex aprendeu a rotear diferentes saídas para streams separados — arquivos de log registram apenas sucessos, o terminal só mostra informações importantes, e os erros são salvos separadamente para solução de problemas.
3. Pontos-Chave
(1) Os Três Streams Padrão
Quando um programa Linux inicia, ele recebe automaticamente três descritores de arquivo:
| Descritor | Nome | Conexão padrão | Finalidade |
|---|---|---|---|
| 0 | stdin | Teclado | Entrada do programa |
| 1 | stdout | Tela do terminal | Saída normal do programa |
| 2 | stderr | Tela do terminal | Saída de erros do programa |
┌──────────┐
stdin ──→│ │──→ stdout
(teclado)│ Programa │ (tela)
│ │──→ stderr
└──────────┘ (tela)
(2) Operadores de Redirecionamento
| Operador | Significado | Exemplo |
|---|---|---|
> |
Escrever stdout em arquivo (sobrescrever) | ls > arquivos.txt |
>> |
Anexar stdout ao arquivo | echo "pronto" >> log.txt |
< |
Ler stdin do arquivo | sort < lista.txt |
2> |
Escrever stderr em arquivo | cmd 2> erro.log |
2>> |
Anexar stderr ao arquivo | cmd 2>> erro.log |
&> |
Escrever tanto stdout quanto stderr em arquivo | cmd &> tudo.log |
&>> |
Anexar tanto stdout quanto stderr em arquivo | cmd &>> tudo.log |
2>&1 |
Mesclar stderr em stdout | cmd > log.txt 2>&1 |
ℹ️ Nota:
>sobrescreve (o conteúdo existente do arquivo é apagado), enquanto>>anexa (adiciona ao final do arquivo). Use>>quando precisar preservar logs históricos; use>quando precisar de um estado limpo. Usar>incorretamente pode sobrescrever arquivos de log importantes.
(3) /dev/null — O Buraco Negro
/dev/null é um arquivo de dispositivo especial — qualquer dado escrito nele é descartado, e a leitura dele não retorna nada.
/dev/null é o "dispositivo buraco negro" do Linux — o kernel descarta diretamente os dados escritos no nível do driver, sem usar espaço em disco, e nunca fica cheio. Comumente usado para silenciar a saída de comandos: command &> /dev/null suprime completamente toda a saída, command 2> /dev/null suprime apenas os erros.
# Descartar toda a saída
command > /dev/null 2>&1
# Ou a forma mais curta
command &> /dev/null
# Descartar apenas os erros
command 2> /dev/null
# Descartar apenas a saída normal
command > /dev/null
(4) ▶ Exemplo: Salvar Saída de Comando em um Arquivo
# Escrita sobrescrevendo
ls ~ > lista-home.txt
cat lista-home.txt
# Escrita anexando
echo "Uma nova linha" >> lista-home.txt
echo "Outra linha" >> lista-home.txt
cat lista-home.txt
Saída:
TEXTDesktop Documents Downloads Uma nova linha Outra linha
(5) ▶ Exemplo: Separar Saída Normal de Saída de Erro
# Salvar mensagens de sucesso, ver erros separadamente
find /etc -name "*.conf" > encontrados.txt 2> erros.txt
# Ver resultados
echo "=== Arquivos de configuração encontrados ==="
head -5 encontrados.txt
echo "=== Mensagens de erro ==="
cat erros.txt
Saída:
TEXT=== Arquivos de configuração encontrados === /etc/adduser.conf /etc/ca-certificates.conf /etc/debconf.conf /etc/deluser.conf /etc/fuse.conf === Mensagens de erro === find: '/etc/ssl/private': Permissão negada
(6) ▶ Exemplo: Mesclar Saída
# Método 1: &> (bash 4+)
grep -r "erro" /var/log/ &> todos-resultados.txt
# Método 2: 2>&1 (mais portátil)
grep -r "erro" /var/log/ > todos-resultados.txt 2>&1
# Ambos os métodos produzem o mesmo resultado — stdout e stderr vão para o mesmo arquivo
2>&1 importa! cmd > log.txt 2>&1 está correto — primeiro redireciona stdout para um arquivo, depois mescla stderr em stdout (que agora aponta para o arquivo). Se escrito como cmd 2>&1 > log.txt, stderr primeiro seria mesclado no stdout da tela, e depois stdout seria redirecionado para o arquivo, deixando stderr indo ainda para a tela.
Saída:
TEXT$ wc -l todos-resultados.txt 42 todos-resultados.txt
(7) ▶ Exemplo: /dev/null Para Suprimir Saída
# Execução completamente silenciosa
sudo apt update > /dev/null 2>&1
# Forma mais curta
sudo apt update &> /dev/null
# Suprimir apenas os erros
find / -name "*.py" 2> /dev/null
Saída:
TEXT(Sem saída — todos os erros e resultados normais suprimidos)
(8) ▶ Exemplo: heredoc — Embutir Texto Multilinha em Scripts
# Criar um arquivo de configuração multilinha
cat << EOF > nginx.conf
server {
listen 80;
server_name exemplo.com;
root /var/www/html;
}
EOF
# Anexar texto multilinha
cat << EOF >> ~/.bashrc
# Adicionar ao PATH
export PATH="\$PATH:\$HOME/scripts"
EOF
# Variáveis em heredoc não serão expandidas (use 'EOF' com aspas)
cat << 'EOF' > saudacao.sh
#!/bin/bash
echo "Olá, $USER" # $USER permanece como nome de variável
EOF
Saída:
TEXTserver { listen 80; server_name exemplo.com; root /var/www/html; }
(9) ▶ Exemplo Abrangente: Gerenciamento de Saída Durante Compilação de Programa
# Compilar um programa C, registrando saída e erros separadamente
gcc main.c -o app \
> build.log \ # Mensagens de sucesso da compilação
2> build-errors.log # Mensagens de erro da compilação
# Se a compilação for bem-sucedida, build-errors.log está vazio
# Se a compilação falhar, veja os erros
if [ -s build-errors.log ]; then
echo "❌ Compilação falhou, erros:"
cat build-errors.log
else
echo "✅ Compilação bem-sucedida!"
fi
❓ Perguntas Frequentes
P: Qual é a diferença entre
>e|(pipe)? R: \1
P: O que significa
2>&1? R: \1
P: Por que usar
&>em vez de2>&1? R:&>é um atalho disponível no bash 4+ que é mais conciso.2>&1é mais portátil (funciona também em sh). Ambos fazem a mesma coisa.
P:
/dev/nullé um vácuo? Pode encher? R: Não. Os dados escritos em/dev/nullsão descartados diretamente pelo kernel, sem usar nenhum espaço em disco. É essencialmente um "buraco negro de capacidade infinita".
P: O
EOFem heredoc precisa ser maiúsculo? R: Não.EOFé apenas uma convenção; você pode usar qualquer string (EOL,END,__EOF__). O importante é que os marcadores de início e fim sejam exatamente iguais.
📖 Resumo
- Entrada padrão (stdin/0) → Programa → Saída padrão (stdout/1) + Erro padrão (stderr/2)
>sobrescreve,>>anexa,2>redireciona erros&>mescla saída,/dev/nulldescarta saída2>&1mescla stderr em stdout (atenção à ordem)- heredoc
<< EOF ... EOFembute texto multilinha em scripts
📝 Exercícios
- Básico (Dificuldade ⭐): Salve a saída de
ls -laemlista-home.txt, depois anexe a data atual com>> - Intermediário (Dificuldade ⭐⭐): Execute
find / -name "*.py" 2> erros.txtpara ver os erros de permissão negada, depois use&>para capturar stdout e stderr em um único arquivo, e use/dev/nullpara suprimir a saída de erros - Avançado (Dificuldade ⭐⭐⭐): Use heredoc para criar um arquivo de configuração com 5 linhas de conteúdo, depois escreva um script demonstrando todos os quatro métodos de redirecionamento (
>,2>,&>e>>) e explique quando cada um é apropriado