Ubuntu Redirecionamento

Normalmente, o que um comando responde aparece na tela. Redirecionar é mandar essa resposta para outro lugar, como um arquivo, ou pegar a entrada de um arquivo em vez do teclado. Com três ou quatro símbolos você salva relatórios, separa erros e cria arquivos de configuração.

Você vai aprender
  • O que são os três canais de todo comando: entrada, saída e erro.
  • A diferença entre > (substitui) e >> (acrescenta).
  • Como separar ou juntar erros com 2>, 2>&1 e /dev/null.
  • Por que sudo echo … > /etc/arquivo dá "Permissão negada", e como resolver.

Os três canais de um comando

Todo programa que roda no terminal nasce com três "canos" ligados. Cada um tem um número, e é por esse número que você o redireciona.

               ┌───────────┐ ── 1 · saída (stdout) ──►  tela
  teclado ──►  │  comando  │
  0 · entrada  └───────────┘ ── 2 · erro (stderr)  ──►  tela
NúmeroNomeEm inglêsPara onde vai, sem redirecionar
0Entrada padrãostandard input, stdinVem do teclado
1Saída padrãostandard output, stdoutVai para a tela: a resposta "normal"
2Saída de errostandard error, stderrVai para a tela também: as mensagens de erro

Como a saída e o erro aparecem na mesma tela, parecem uma coisa só. Mas são canais separados, e isso vai fazer diferença daqui a pouco.


Gravar a saída num arquivo: >

O sinal > (maior que) pega a saída do comando e grava num arquivo, em vez de mostrar na tela.

ls Documentos
O comando, que normalmente mostraria a lista na tela.
>
"Mande a saída (canal 1) para…"
lista.txt
…este arquivo. Se não existir, é criado.
$ ls Documentos > lista.txt
$ cat lista.txt
acesso.log
notas.txt
projetos
relatorio.odt

Repare em duas coisas:

  • O primeiro comando não mostrou nada: a lista foi para o arquivo, não para a tela.
  • No arquivo, cada nome está numa linha. Quando a saída não é a tela, o ls não organiza em colunas nem colore.

Atenção: > substitui o conteúdo

Se o arquivo já existe, o > apaga tudo o que havia nele antes de gravar. Ele não pergunta.

$ echo "primeira linha" > teste.txt
$ echo "segunda linha" > teste.txt
$ cat teste.txt
segunda linha                       « a primeira sumiu
O arquivo é esvaziado antes de o comando rodar

O shell prepara o redirecionamento antes de executar o comando. Por isso, sort frutas.txt > frutas.txt apaga o arquivo: quando o sort vai ler, ele já está vazio. Grave sempre num arquivo diferente.


Acrescentar ao final: >>

Dois sinais, >>, gravam no fim do arquivo, sem apagar o que já estava lá. É o que você quer para diários, logs e listas.

echo "kiwi"
Produz uma linha de texto.
>>
"Acrescente ao final de…" (append).
frutas.txt
O arquivo. Também é criado se não existir.
$ echo "kiwi" >> frutas.txt
$ tail -n 3 frutas.txt
maçã
banana
kiwi                                « a linha nova entrou no fim

Um uso clássico é registrar quando algo aconteceu:

$ echo "$(date +%F) backup feito" >> diario.txt
$ cat diario.txt
2026-10-15 backup feito

Missão: grave a lista de arquivos da pasta Downloads num arquivo chamado downloads.txt. Depois acrescente, no fim dele, a linha fim da lista. Confira com cat downloads.txt.


Prova: o erro "vaza" para a tela

Agora vamos pedir dois itens ao ls: a pasta Documentos, que existe, e nada, que não existe. A saída vai para um arquivo. Veja o que acontece:

$ ls Documentos nada > saida.txt
ls: não é possível acessar 'nada': Arquivo ou diretório inexistente    « apareceu mesmo assim!
$ cat saida.txt
Documentos:
acesso.log
notas.txt
projetos
relatorio.odt                                                         « o arquivo só tem a parte boa

O > redireciona só o canal 1 (saída). A mensagem de erro sai pelo canal 2, que continua apontando para a tela. Para mexer no erro, você precisa dizer o número dele.


Redirecionar erros: 2>

ls Documentos nada
Um comando que vai produzir saída e erro.
2>
"Mande o canal 2 (erros) para…". Sem espaço entre o 2 e o >.
erros.txt
…este arquivo.
$ ls Documentos nada 2> erros.txt
Documentos:
acesso.log  notas.txt  projetos  relatorio.odt                         « a saída boa veio para a tela
$ cat erros.txt
ls: não é possível acessar 'nada': Arquivo ou diretório inexistente   « o erro foi para o arquivo

Para não apagar erros antigos, use 2>>, que acrescenta.

Jogar fora: /dev/null

/dev/null é um arquivo especial que descarta tudo o que recebe. É o "buraco negro" do Linux. Ele é útil quando você só quer o resultado e não se importa com os avisos.

Exemplo: procurar o arquivo hostname no sistema inteiro. Sem redirecionar, as pastas proibidas enchem a tela de "Permissão negada":

$ find / -name hostname
find: ‘/root’: Permissão negada                « ruído
/etc/hostname
$ find / -name hostname 2>/dev/null
/etc/hostname                                  « só o que interessa
Descartar a saída também

comando > /dev/null descarta a resposta normal e deixa os erros. É útil quando você só quer saber se o comando deu certo, olhando o código $?.

Missão: rode ls Imagens nada mandando só os erros para o arquivo erros.txt. A lista de imagens deve continuar aparecendo na tela. Depois, rode find / -name hosts sem que nenhuma mensagem de erro apareça.


Saída e erro no mesmo arquivo: 2>&1

Às vezes você quer tudo junto, por exemplo num log. Para isso, primeiro mande a saída para o arquivo e, depois, diga que o erro (2) vai para o mesmo lugar da saída (1).

ls Documentos nada
O comando.
> tudo.txt
Primeiro: a saída (1) vai para tudo.txt.
2>&1
Depois: o erro (2) vai para onde o 1 aponta agora. O & indica que 1 é um canal, não um arquivo chamado "1".
$ ls Documentos nada > tudo.txt 2>&1
$ cat tudo.txt
ls: não é possível acessar 'nada': Arquivo ou diretório inexistente
Documentos:
acesso.log
notas.txt
projetos
relatorio.odt

O Bash tem um atalho que faz a mesma coisa: &>.

$ ls Documentos nada &> tudo.txt
A ordem importa

comando 2>&1 > arquivo não junta os dois. O 2>&1 é lido primeiro, quando o 1 ainda aponta para a tela. Então o erro continua na tela, e só a saída vai para o arquivo. Escreva sempre > arquivo 2>&1.


Ler a entrada de um arquivo: <

O < faz o caminho contrário: em vez do teclado, a entrada (canal 0) vem de um arquivo. Muitos comandos aceitam o nome do arquivo direto, mas há uma diferença sutil:

$ wc -l frutas.txt
7 frutas.txt                 « o wc abriu o arquivo e sabe o nome dele
$ wc -l < frutas.txt
7                            « o wc só recebeu o conteúdo, sem nome

A segunda forma é ótima para scripts, quando você quer só o número:

$ echo "Tenho $(wc -l < frutas.txt) frutas na lista"
Tenho 7 frutas na lista

Texto no próprio comando: here-doc e here-string

O here-doc ("documento aqui") envia várias linhas digitadas como entrada. Ele começa com <<FIM e termina na linha que tem só FIM. Junto com >, é a forma mais prática de criar um arquivo de várias linhas dentro de um script.

cat
Repete o que recebe.
<<FIM
"A entrada são as próximas linhas, até aparecer FIM." O nome FIM é livre; EOF é o mais comum.
> config.txt
Grava o resultado no arquivo.
$ cat <<FIM > config.txt
> nome=loja
> porta=8080
> FIM
$ cat config.txt
nome=loja
porta=8080

O > no começo das linhas do meio é o prompt de continuação do Bash. Você não digita esse sinal.

A here-string, <<<, manda uma única linha:

$ tr a-z A-Z <<< "ola mundo"
OLA MUNDO

O simulador desta página ainda não entende here-doc nem here-string. Teste esses dois no seu terminal.


Formas diferentes de criar um arquivo com texto

FormaExemploMelhor quando…
echo + >echo "porta=80" > app.confÉ uma linha só.
printf + >printf "a\nb\n" > lista.txtSão poucas linhas e você quer controlar as quebras.
here-doccat <<EOF > app.conf … EOFSão várias linhas, dentro de um script.
teeecho "x" | sudo tee /etc/app.confO arquivo é do root (veja abaixo).
Editornano app.confVocê vai digitar e revisar com calma.

Redirecionamento com sudo

Este é um dos erros mais comuns de quem está começando:

$ sudo echo "8.8.8.8 dns" >> /etc/hosts
bash: /etc/hosts: Permissão negada

Por quê? O sudo vale só para o echo. Quem abre o arquivo /etc/hosts para escrever é o seu shell, que roda como você, sem poder de administrador. E ele faz isso antes até de o sudo começar.

Como resolver: deixe o echo como usuário comum e use o tee com sudo para escrever. O -a do tee acrescenta, como o >>:

$ echo "8.8.8.8 dns" | sudo tee -a /etc/hosts
[sudo: authenticate] Senha:
8.8.8.8 dns                     « o tee também mostra o que gravou

O | (pipe) e o tee são explicados em Pipes e xargs.


Quando não funciona

O arquivo ficou vazio
$ sort frutas.txt > frutas.txt
$ cat frutas.txt
$ wc -l frutas.txt
0 frutas.txt                      « o arquivo foi esvaziado

O que aconteceu: o > esvaziou frutas.txt antes de o sort ler.

Como resolver: grave em outro arquivo e depois renomeie: sort frutas.txt > ordenado.txt && mv ordenado.txt frutas.txt. O conteúdo perdido não volta, a não ser que você tenha backup.

"impossível sobrescrever arquivo existente"
$ echo "teste" > tudo.txt
bash: tudo.txt: impossível sobrescrever arquivo existente

O que aconteceu: a proteção noclobber está ligada (alguém rodou set -o noclobber ou colocou isso no ~/.bashrc). Ela impede que o > apague arquivos que já existem.

Como resolver: se tiver certeza, force com >|: echo "teste" >| tudo.txt. Para desligar a proteção: set +o noclobber.

"Arquivo ou diretório inexistente" ao gravar
$ ls > relatorios/hoje.txt
bash: relatorios/hoje.txt: Arquivo ou diretório inexistente

O que aconteceu: o > cria o arquivo, mas não cria pastas. A pasta relatorios não existe.

Como resolver: mkdir -p relatorios e repita o comando.

Usei 2>&1 e o erro continuou na tela
$ ls Documentos nada 2>&1 > tudo.txt
ls: não é possível acessar 'nada': Arquivo ou diretório inexistente

O que aconteceu: a ordem está trocada. Quando o 2>&1 foi lido, o canal 1 ainda era a tela.

Como resolver: ls Documentos nada > tudo.txt 2>&1, ou o atalho &> tudo.txt.


Referência

OperadorO que fazExemplo
>Saída para arquivo (substitui)ls > lista.txt
>>Saída para arquivo (acrescenta)echo "x" >> log.txt
2>Erros para arquivo (substitui)cmd 2> erros.txt
2>>Erros para arquivo (acrescenta)cmd 2>> erros.txt
> arq 2>&1Saída e erros no mesmo arquivocmd > tudo.log 2>&1
&>Atalho do Bash para o anteriorcmd &> tudo.log
2>/dev/nullDescarta os errosfind / -name x 2>/dev/null
>/dev/nullDescarta a saídacmd >/dev/null
<Entrada a partir de arquivowc -l < frutas.txt
<<EOFHere-doc: várias linhas como entradacat <<EOF > a.txt
<<<Here-string: uma linha como entradatr a-z A-Z <<< "oi"
>|Sobrescreve mesmo com noclobberecho x >| a.txt

Missão final: (1) grave em ranking.txt o resultado de sort frutas.txt | uniq -c. (2) Rode ls Documentos nada gravando saída e erro juntos em log.txt. Confira os dois arquivos com cat.


Exercícios

1. Acrescentar sem apagar

Complete para adicionar a linha "reunião às 15h" ao fim de agenda.txt, sem perder o que já está lá:

echo "reunião às 15h" agenda.txt

2. Esconder os erros

Complete para buscar arquivos .conf no sistema inteiro sem ver as mensagens de "Permissão negada":

find / -name "*.conf"

3. Tudo no mesmo log

Complete para gravar saída e erros de ./backup.sh no arquivo backup.log:

./backup.sh > backup.log

4. Você rodou ls Documentos nada > saida.txt. O que acontece com a mensagem de erro sobre "nada"?

5. Por que sudo echo "x" > /etc/teste dá "Permissão negada"?


Resumo

  • Todo comando tem três canais: 0 (entrada), 1 (saída) e 2 (erro).
  • > grava substituindo, >> grava acrescentando. Os dois criam o arquivo, mas não a pasta.
  • 2> mexe só nos erros; 2>/dev/null joga os erros fora.
  • Para juntar tudo: > arquivo 2>&1, nessa ordem, ou &> arquivo.
  • < usa um arquivo como entrada. Para escrever em arquivos do root, use | sudo tee.