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.
- 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>&1e/dev/null. - Por que
sudo echo … > /etc/arquivodá "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úmero | Nome | Em inglês | Para onde vai, sem redirecionar |
|---|---|---|---|
0 | Entrada padrão | standard input, stdin | Vem do teclado |
1 | Saída padrão | standard output, stdout | Vai para a tela: a resposta "normal" |
2 | Saída de erro | standard error, stderr | Vai 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
lsnã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 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
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 que1é 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
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
| Forma | Exemplo | Melhor quando… |
|---|---|---|
echo + > | echo "porta=80" > app.conf | É uma linha só. |
printf + > | printf "a\nb\n" > lista.txt | São poucas linhas e você quer controlar as quebras. |
| here-doc | cat <<EOF > app.conf … EOF | São várias linhas, dentro de um script. |
tee | echo "x" | sudo tee /etc/app.conf | O arquivo é do root (veja abaixo). |
| Editor | nano app.conf | Você 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
$ 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.
$ 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.
$ 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.
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
| Operador | O que faz | Exemplo |
|---|---|---|
> | 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>&1 | Saída e erros no mesmo arquivo | cmd > tudo.log 2>&1 |
&> | Atalho do Bash para o anterior | cmd &> tudo.log |
2>/dev/null | Descarta os erros | find / -name x 2>/dev/null |
>/dev/null | Descarta a saída | cmd >/dev/null |
< | Entrada a partir de arquivo | wc -l < frutas.txt |
<<EOF | Here-doc: várias linhas como entrada | cat <<EOF > a.txt |
<<< | Here-string: uma linha como entrada | tr a-z A-Z <<< "oi" |
>| | Sobrescreve mesmo com noclobber | echo 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á:
2. Esconder os erros
Complete para buscar arquivos .conf no sistema inteiro sem ver as mensagens de "Permissão negada":
3. Tudo no mesmo log
Complete para gravar saída e erros de ./backup.sh no arquivo 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/nulljoga 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.