Entendendo stdin, stdout e stderr
O que você vai conseguir fazer
- Distinguir entrada padrão, saída padrão e saída de erro
- Imaginar para onde vão a entrada e a saída de um comando
Pré-requisitos (leia estes primeiro)
O Que São os Fluxos Padrão?
À medida que você aprende a linha de comando, continua encontrando símbolos como > arquivo e | (pipe). Por trás deles está um mecanismo chamado fluxos padrão: stdin, stdout e stderr.
Este guia explica o papel de cada fluxo, por que a saída é dividida em dois tipos, e como redirecionamento e pipes trocam para onde vão a entrada e a saída — tudo por meio de uma conversa entre Lina e Veterano Linny.
O Que Você Vai Aprender
- Do que cada um de stdin, stdout e stderr é responsável
- Por que a saída é dividida em dois fluxos (stdout e stderr)
- O significado dos números 0 / 1 / 2 (descritores de arquivo)
- Como trocar destinos com
>,2>e&> - Como usar o pipe
|e o redirecionamento de entrada<
1. O Que São os Fluxos Padrão?
Conclusão: Os fluxos padrão são três caminhos que um comando usa. Uma entrada recebe dados, e duas saídas enviam resultados e erros. Eles são chamados de stdin, stdout e stderr.
- Entrada padrão (stdin. A porta por onde os dados entram): corresponde à entrada por onde os materiais chegam
- Saída padrão (stdout. A saída dos resultados): corresponde à saída por onde os produtos acabados saem
- Saída de erro padrão (stderr. A saída só para erros): corresponde ao alarme que sinaliza um defeito
Figura 1: uma entrada (stdin) e duas saídas (stdout e stderr). Os números entre parênteses são explicados em "O Que São os Números 0 / 1 / 2?".
O que "padrão" significa
"Padrão" significa "o caminhoUma sequência de texto que descreve a localização de um arquivo ou diretório. padrão usado a menos que você diga o contrário". Por exemplo, o resultado de ls aparece na tela porque o destino padrão do stdout é a tela (o terminalUm programa interativo que interpreta os comandos digitados e os executa.). Redirecionamento e pipes são só formas de mudar esse destino depois.
2. Por Que a Saída É Dividida em stdout e stderr?
Conclusão: Para manter "resultados que você quer passar adiante" separados de "erros que um humano deve ler". Dividi-los permite salvar apenas os resultados, ou capturar apenas os erros.
- stdout = resultados normais (dados que você quer passar adiante ou salvar)
- stderr = erros e avisos (mensagens destinadas a um humano)
Voltando ao exemplo da fábrica
stdout é a esteira que carrega produtos acabados. stderr é o alarme que sinaliza um defeito. Você não quer o som do alarme dentro da caixa de produtos acabados (o arquivo). Por isso são mantidos separados.
3. O Que São os Números 0 / 1 / 2?
Conclusão: stdin, stdout e stderr recebem os números 0, 1 e 2 (descritores de arquivo). O
2em2>se refere a esse número.
2> em um exemplo. O que é esse 2?| Número | Nome | Função |
|---|---|---|
| 0 | stdin | Entrada padrão (entrada) |
| 1 | stdout | Saída padrão (saída normal) |
| 2 | stderr | Erro padrão (saída de erro) |
Como os números se mapeiam para símbolos
Os símbolos de redirecionamento se conectam diretamente a esses números.
>é abreviação de1>(envia stdout)2>envia stderr<é abreviação de0<(lê stdin)
Assim que você lembrar "o 2 em 2> é o número de camisa do stderr", os símbolos passam a fazer sentido.
4. Como Eu Mudo Para Onde a Saída Vai?
Conclusão: Use
>para enviar stdout e2>para enviar stderr para um arquivo. Para combinar ambos, use> arquivo 2>&1ou&> arquivo.
ls /etc > filelist.txt
Com >, o conteúdo de stdout que apareceria na tela é escrito em filelist.txt. Nada aparece na tela. Note que > sobrescreve, enquanto >> anexa.
> é útil. Deixa eu testar. Rodei ls /etc > notas.txt, e logo depois rodei ls /home > notas.txt também.notas.txt na primeira vez.> só sobrescreve. Aponte para o mesmo nome de arquivo de novo, e o conteúdo antigo some. Para manter os dois, use >> (anexar).> não "salva" — ele "substitui"...! Vou usar >> daqui pra frente.Cuidado com sobrescritas acidentais usando >
Ao salvar um arquivo em um app com interface gráfica, você recebe um aviso: "Já existe um arquivo com esse nome. Deseja sobrescrever?" O > não tem esse aviso. No instante em que você pressiona Enter, o conteúdo antigo desaparece — e nem vai para a lixeira.
Para usar com segurança, crie estes dois hábitos:
- Use
>>(anexar) quando quiser manter o conteúdo anterior - Verifique com
ls nome-do-arquivoantes de salvar, para ver se já existe um arquivo com esse nome
Vale lembrar que o terminal virtual deste site é para fins de aprendizado. Testar > aqui não vai danificar nenhum arquivo do seu computador, então pratique à vontade.
Para salvar apenas os erros, use 2>.
ls /not-exist 2> errors.txt
Desta vez, nada aparece na tela. O arquivo errors.txt registra a seguinte linha.
ls: cannot access '/not-exist': No such file or directory
> e stderr é 2>. E se eu quiser ambos em um arquivo?2>&1. Significa "enviar stderr (2) para o mesmo destino que stdout (1)".command > output.txt 2>&1
A ordem importa com 2>&1
2>&1 significa "fazer stderr corresponder ao destino atual de stdout". Então você deve escrever > output.txt primeiro. Inverta a ordem, como em command 2>&1 > output.txt, e stderr fica apontado para seu destino antigo (a tela). Se você não quiser se preocupar com a ordem, a notação &> arquivo também envia ambos de uma vez. Vale notar que essa é uma sintaxe específica do bash — o shell usado por padrão em sistemas como o Ubuntu, o programa que recebe e executa os comandos que você digita.
command &> output.txt
5. Como Pipes e Entrada Padrão Funcionam?
Conclusão: Um pipe
|conecta o stdout do comando da esquerda ao stdin do comando da direita.<alimenta o conteúdo de um arquivo como stdin.
| conecta o stdout do comando da esquerda diretamente ao stdin do comando da direita.ls /etc | grep conf
Neste exemplo, a saída (stdout) de ls /etc flui diretamente para a entrada (stdin) de grep conf. O grep então seleciona apenas as linhas que contêm conf.
Visualize o fluxo
ls /etc ──stdout──▶ | ──stdin──▶ grep conf ──stdout──▶ tela
Um pipe é como uma mangueira que conecta a saída do comando anterior diretamente à entrada do próximo comando.
Para alimentar o conteúdo de um arquivo como stdin, use <.
sort < names.txt
Isso transmite o conteúdo de names.txt para a entrada padrão do sort, que os ordena e imprime. O resultado é o mesmo que sort names.txt. Mas isso torna fácil visualizar o comportamento de "conectar um arquivo ao stdin" da entrada padrão.
Para praticar pipes e redirecionamento de forma mais prática, veja Fundamentos de Pipes e Redirecionamento. Quando você quiser que a saída vá tanto para a tela quanto para um arquivo, Como Usar o Comando tee é útil.
Mini Exercícios
Conclusão: Pratique redirecionar stdout e stderr, e usar pipes, testando você mesmo.
Exercício 1: Salve apenas o resultado de ls /etc em etc-list.txt (nada deve aparecer na tela)
Ver Dica 1 (Direção)
Existe um símbolo que troca para onde vai a saída, da tela para um arquivo. Sobrescrever está tudo bem aqui.
Ver Dica 2 (Nome do Comando)
Use >.
Ver Resposta
ls /etc > etc-list.txt
Nada aparece na tela. etc-list.txt agora contém a listagem de /etc.
Exercício 2: Aponte ls para um diretórioUm local que organiza arquivos. É a mesma ideia da "pasta" do Windows ou macOS. que não existe, e salve apenas a mensagem de erro em err.txt (nenhum erro deve aparecer na tela)
Ver Dica 1 (Direção)
Existe um símbolo que direciona apenas a saída de erro — não a saída normal — para um arquivo.
Ver Dica 2 (Nome do Comando)
Use 2>.
Ver Resposta
ls /no-such-dir 2> err.txt
Nada aparece na tela. err.txt registra ls: cannot access '/no-such-dir': No such file or directory.
Exercício 3: Mostre apenas as linhas de ls /etc que contêm conf, na tela (não salve em um arquivo)
Ver Dica 1 (Direção)
Existe um mecanismo que alimenta a saída de um comando diretamente como entrada do próximo comando.
Ver Dica 2 (Nome do Comando)
Use o pipe | com grep.
Ver Resposta
ls /etc | grep conf
Apenas as linhas de ls /etc que contêm conf aparecem na tela.
Resumo
- Os fluxos padrão são três caminhos: stdin (entrada), stdout (saída normal) e stderr (saída de erro)
- Há dois fluxos de saída para evitar a mistura de "resultados" e "erros"
- Os três recebem os números 0 / 1 / 2 (descritores de arquivo)
- Use
>para stdout e2>para stderr para enviá-los a um arquivo (ambos com> arquivo 2>&1ou&> arquivo) - Um pipe
|conecta stdout ao próximo stdin, e<alimenta um arquivo como stdin