Percursos
/
Bash
Bash
/
Programa
/
Redirecionamento
Re

Redirecionamento em Bash

{one: "1 exercício", many: "%{count} exercícios", other: "%{count} exercícios"}

Sobre Redirecionamento

No mundo da interface de linha de comandos, os programas interagem frequentemente com três fluxos de dados padrão:

  1. Entrada padrão (stdin): onde um programa recebe a sua entrada (normalmente a partir do teclado).
  2. Saída padrão (stdout): onde um programa envia a sua saída normal (normalmente para o ecrã do terminal).
  3. Erro padrão (stderr): onde um programa envia as mensagens de erro (normalmente para o ecrã do terminal).

Recorda-te de que os apresentámos no capítulo Pipelines e Listas de Comandos.

Note

As pipelines podem ser consideradas uma forma de redirecionamento: a saída padrão de um programa é enviada diretamente para a entrada padrão de outro. Já abordámos as pipelines. Este conceito vai abordar o redirecionamento de e para ficheiros.

O redirecionamento da shell é um mecanismo poderoso que te permite alterar o destino destes fluxos. Em vez de um programa ler do teclado ou escrever para o ecrã, podes redirecionar a entrada a partir de um ficheiro ou enviar a saída para um ficheiro. Isto dá-te bastante flexibilidade e controlo sobre a forma como os programas interagem com os dados.

Principais Operadores de Redirecionamento

Eis os operadores de redirecionamento mais comuns e o que fazem:

> (Redirecionamento de Saída)

  • Objetivo: redirecionar a saída padrão (stdout) de um comando para um ficheiro.

  • Comportamento:

    • Se o ficheiro não existir, é criado.
    • Se o ficheiro existir, o seu conteúdo é substituído.
  • Exemplo:

    # Sends the output of 'ls -l' to 'file_listing.txt'
    ls -l > file_listing.txt
    
Caution

O redirecionamento é feito antes de o comando ser executado. Isto significa que não podes redirecionar para o mesmo ficheiro de onde precisas de 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,

  1. O Bash trunca primeiro o ficheiro indicado no redirecionamento. Isto destrói o conteúdo anterior, deixando um ficheiro vazio.
  2. Em seguida, o Bash lê o ficheiro agora vazio.
  3. Depois, o Bash escreve o conteúdo (ou seja, nada) de volta para o ficheiro.

>> (Redirecionamento de Saída com Acréscimo)

  • Objetivo: acrescentar a saída padrão (stdout) de um comando a um ficheiro.

  • Comportamento:

    • Se o ficheiro não existir, é criado.
    • Se o ficheiro existir, a saída é adicionada ao fim do ficheiro.
  • 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 ficheiro.

  • Comportamento: o comando lê a sua entrada a partir do ficheiro 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 Erros):

  • Objetivo: redirecionar o erro padrão (stderr) de um comando para um ficheiro.
  • Comportamento: as mensagens de erro são enviadas para o ficheiro indicado em vez do terminal.
  • Exemplo:
    # Error message from 'rm' is sent to 'error_log.txt'
    rm non_existent_file 2> error_log.txt
    

Podes acrescentar o erro padrão a um ficheiro com 2>>.

Outros Redirecionamentos

Existem também redirecionamentos que podem combinar stdin e stderr. Consulta o manual para mais detalhes.

/dev/null

/dev/null é um ficheiro especial que

  • está vazio quando lês a partir dele, e
  • descarta todos os dados que lhe são escritos.

Por vezes é também chamado de «the bitbucket». É útil para suprimir a saída ou os 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

Combinar redirecionamentos

Podem indicar-se 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 vês 2>&1, lê isso como «redireciona o stderr para aquilo para onde o stdout está neste momento a apontar». O Bash processa as instruções de redirecionamento estritamente da esquerda para a direita, o que significa que podes 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
Advanced

Descritores de Ficheiro

No contexto da programação de shell e de sistemas operativos como Linux/Unix, um descritor de ficheiro (FD, do inglês file descriptor) é um número inteiro não negativo que serve como identificador ou referência para um ficheiro aberto ou um recurso de E/S (Entrada/Saída). Pensa nisso como uma etiqueta ou um número de referência que o sistema operativo usa para acompanhar os ficheiros abertos e os fluxos de dados.

Os números que vês à esquerda dos redirecionamentos são descritores de ficheiro.

Os fluxos de E/S padrão recebem os primeiros três descritores de ficheiro:

  • a entrada padrão é o FD 0
  • a saída padrão é o FD 1
  • o erro padrão é o FD 2

Podem definir-se ou criar-se novos descritores de ficheiro com o comando exec e os 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'

Esta técnica parece bastante complicada, mas pode ser muito útil em situações em que o teu script está a ser executado por outro pacote de software e a saída padrão é capturada automaticamente por esse software. O comando bats que é usado para correr os testes unitários deste track funciona assim: o bats captura o stdout e o stderr de um teste, mas as mensagens de depuração enviadas para o FD 3 são apresentadas no terminal.

Em Resumo

Porque é que o redirecionamento é útil?

  • Guardar a saída: armazenar os resultados de um comando para consulta ou processamento posterior.
  • Registo: capturar mensagens de erro para depuração.
  • Automatização: encadear comandos, usando a saída de um como entrada de outro.
  • Filtragem: descartar a saída indesejada.
  • Processamento em lote: processar dados a partir de ficheiros em vez de os escrever manualmente.
  • Escrita de scripts: os redirecionamentos são essenciais para escrever scripts de shell robustos.

Os redirecionamentos da shell dão-te um controlo preciso sobre a forma como os programas interagem com os dados, permitindo-te construir fluxos de trabalho complexos e gerir a informação de forma eficaz.

Editar via GitHub A ligação abre numa nova janela ou separador