No mundo da interface de linha de comando, os programas costumam interagir com três fluxos de dados padrão:
stdin): de onde um programa recebe sua entrada (normalmente do teclado).stdout): para onde um programa envia sua saída normal (normalmente para a tela do terminal).stderr): para onde um programa envia mensagens de erro (normalmente para a tela do terminal).Lembre-se de que apresentamos esses fluxos no capítulo Pipelines e listas de comandos.
Os pipelines podem ser considerados uma forma de redirecionamento: a saída padrão de um programa é enviada diretamente para a entrada padrão de outro. Já falamos sobre pipelines. Este conceito vai abordar o redirecionamento de e para arquivos.
O redirecionamento do shell é um mecanismo poderoso que permite mudar o destino desses fluxos. Em vez de um programa ler do teclado ou escrever na tela, você pode redirecionar a entrada de um arquivo ou enviar a saída para um arquivo. Isso dá bastante flexibilidade e controle sobre como os programas interagem com os dados.
Veja os operadores de redirecionamento mais comuns e o que eles fazem:
> (redirecionamento de saída)Objetivo: redirecionar a saída padrão (stdout) de um comando para um arquivo.
Comportamento:
Exemplo:
# Sends the output of 'ls -l' to 'file_listing.txt'
ls -l > file_listing.txt
O redirecionamento acontece antes de o comando ser executado. Isso significa que você não pode redirecionar para o mesmo arquivo de onde precisa ler.
date > date.txt # populate the file with the current date
cat date.txt > date.txt # 'date.txt' is now empty!
No segundo comando do exemplo acima,
>> (redirecionamento de acréscimo à saída)Objetivo: acrescentar a saída padrão (stdout) de um comando a um arquivo.
Comportamento:
Exemplo:
# Adds "Another line" to the end of the file
echo "Another line" >> file_listing.txt
< (redirecionamento de entrada)Objetivo: redirecionar a entrada padrão (stdin) de um comando a partir de um arquivo.
Comportamento: o comando lê a entrada do arquivo indicado em vez do teclado.
Exemplo:
# 'tr' reads from 'lowercase.txt' and
# output is redirected to 'uppercase.txt'
tr 'a-z' 'A-Z' < lowercase.txt > uppercase.txt
2> (redirecionamento de erro):stderr) de um comando para um arquivo.# Error message from 'rm' is sent to 'error_log.txt'
rm non_existent_file 2> error_log.txt
Você pode acrescentar o erro padrão a um arquivo com 2>>.
Também existem redirecionamentos que podem juntar stdin e stderr.
Consulte o manual para mais detalhes.
/dev/null/dev/null é um arquivo especial que
Às vezes ele é chamado de "bitbucket". Ele é útil para suprimir saída ou erros.
some_command > /dev/null # Discards stdout
some_command 2> /dev/null # Discards stderr
# Using /dev/null as input will prevent the command
# from reading data from the keyboard
some_command < /dev/null
É possível usar vários redirecionamentos ao mesmo tempo.
some_command < input.txt > output.txt 2> error.txt
Um redirecionamento pode ser copiado.
# send stderr to the same destination as stdout
some_command > output.txt 2>&1
Quando você vir 2>&1, leia como "redirecione o stderr para onde quer que o stdout esteja apontando no momento".
O Bash processa as instruções de redirecionamento estritamente da esquerda para a direita, o que significa que você pode fazer:
# redirect stdout to 'output1.txt'
# redirect stderr to the same place
# then change stdout to 'output2.txt'
some_command > output1.txt 2>&1 > output2.txt
No contexto da programação de shell e de sistemas operacionais como Linux/Unix, um descritor de arquivo (FD) é um número inteiro não negativo que serve como identificador ou referência para um arquivo aberto ou um recurso de E/S (Entrada/Saída). Pense nele como um rótulo ou um número de referência que o sistema operacional usa para acompanhar arquivos abertos e fluxos de dados.
Os números que você vê no lado esquerdo dos redirecionamentos são descritores de arquivo.
Os fluxos de E/S padrão recebem os três primeiros descritores de arquivo:
Novos descritores de arquivo podem ser definidos ou criados com o comando exec e operadores de redirecionamento.
# create FD 3 as a copy of stdout
exec 3>&1
# send stdout to a log file
exec > log.txt
# then redirect both stdout and file descriptor 3
echo "some debug message" >&3 # displayed in the terminal
some_command 2>&1 # stdout and stderr send to 'log.txt'
Essa técnica parece bastante complicada, mas pode ser muito útil em situações nas quais seu script é executado por outro pacote de software e a saída padrão é capturada automaticamente por ele.
O comando bats, usado para rodar os testes de unidade desta trilha, funciona assim: o bats captura a saída padrão e a saída de erro de um teste, mas as mensagens de depuração enviadas ao FD 3 são exibidas no terminal.
Por que o redirecionamento é útil?
Os redirecionamentos do shell dão a você um controle preciso sobre como os programas interagem com os dados, permitindo montar fluxos de trabalho complexos e gerenciar informações com eficiência.