O redirecionamento de E/S (entrada/saída) é um dos recursos mais poderosos do shell Linux/Bash. Ele permite que você controle de onde um comando lê sua entrada e para onde ele escreve sua saída, seja para um arquivo, para outro comando ou até mesmo para o vazio. Compreender esses mecanismos é essencial para automatizar tarefas, gerenciar logs e construir pipelines eficientes.

Nesta aula, vamos explorar os três descritores de arquivo padrão (stdin, stdout, stderr), os operadores de redirecionamento mais comuns e o uso do dispositivo /dev/null. Todos os exemplos são práticos e podem ser testados diretamente no terminal.

stdin, stdout, stderr

No Linux, todo processo possui três canais de E/S padrão, identificados por números chamados descritores de arquivo (file descriptors):

  • stdin (descritor 0): Entrada padrão. Por padrão, é o teclado. Comandos que leem entrada do usuário (como read, cat sem argumentos) utilizam stdin.
  • stdout (descritor 1): Saída padrão. Por padrão, é o terminal. A saída normal dos comandos (como listagens, mensagens de sucesso) vai para stdout.
  • stderr (descritor 2): Saída de erro padrão. Por padrão, também é o terminal, mas é usada exclusivamente para mensagens de erro e diagnóstico. Separar erros da saída normal é crucial para depuração.

Exemplo: o comando ls lista arquivos no diretório atual. Se o diretório não existir, a mensagem de erro vai para stderr. Para ver a diferença, experimente:

ls /existe /naoexiste

A saída de /existe (se existir) vai para stdout; o erro de /naoexiste vai para stderr. Ambos aparecem no terminal, mas são canais distintos.

> e >>

O operador > redireciona stdout para um arquivo, sobrescrevendo o conteúdo existente. O operador >> redireciona stdout para um arquivo, mas anexa ao final (append).

Exemplo com >:

echo "Linha 1" > arquivo.txt
cat arquivo.txt
# Saída: Linha 1

Exemplo com >>:

echo "Linha 2" >> arquivo.txt
cat arquivo.txt
# Saída:
# Linha 1
# Linha 2

Se o arquivo não existir, ambos os operadores o criam. A diferença é que > substitui o conteúdo, enquanto >> adiciona ao final.

2> e &>

Para redirecionar stderr (descritor 2), usamos 2>. O número 2 antes do > indica o descritor a ser redirecionado.

Exemplo: redirecionar erros para um arquivo separado:

ls /existe /naoexiste 2> erros.txt
cat erros.txt
# Saída: ls: cannot access '/naoexiste': No such file or directory

Para redirecionar tanto stdout quanto stderr para o mesmo arquivo, usamos &>:

ls /existe /naoexiste &> tudo.txt
cat tudo.txt
# Saída inclui tanto a listagem (se existir) quanto o erro

Outra forma comum é 2>&1, que redireciona stderr para onde stdout está indo. Por exemplo:

ls /existe /naoexiste > saida.txt 2>&1

Nesse caso, stdout vai para saida.txt e stderr também, pois 2>&1 diz "stderr vá para o mesmo lugar que stdout".

/dev/null

/dev/null é um dispositivo especial que descarta toda a informação que é escrita nele. É como um "buraco negro" para dados. Muito útil quando você quer ignorar saídas ou erros indesejados.

Exemplo: descartar erros:

ls /naoexiste 2> /dev/null

Nenhum erro aparecerá no terminal. Para descartar toda a saída (stdout e stderr):

ls /naoexiste &> /dev/null

Também é comum usar /dev/null como entrada vazia para comandos que esperam stdin, como:

cat < /dev/null

Isso retorna imediatamente sem ler nada.

Boas práticas

  • Sempre redirecione stderr em scripts para evitar que erros poluam a saída normal.
  • Use > com cuidado, pois sobrescreve arquivos. Prefira >> para logs.
  • Combine redirecionamentos com pipes (|) para criar pipelines poderosos.
  • Teste redirecionamentos em um diretório temporário para evitar perda de dados.

Referências

Exercícios

  1. Escreva um comando que liste o conteúdo do diretório /etc e salve a saída normal em lista.txt e os erros em erros.txt.

    ✓ Resposta:
    ls /etc > lista.txt 2> erros.txt
  2. Como você pode descartar completamente a saída (stdout e stderr) de um comando?

    ✓ Resposta:
    comando &> /dev/null
  3. Qual a diferença entre > e >>?

    ✓ Resposta:

    > sobrescreve o conteúdo do arquivo de destino, enquanto >> anexa (adiciona ao final).

  4. Explique o que faz o comando: comando 2>&1 | outro_comando

    ✓ Resposta:

    Redireciona stderr para o mesmo destino que stdout (que é o pipe), de forma que tanto stdout quanto stderr do primeiro comando sejam enviados como entrada para outro_comando.

  5. Crie um comando que adicione a linha "Fim" ao final do arquivo log.txt sem sobrescrever o conteúdo existente.

    ✓ Resposta:
    echo "Fim" >> log.txt