Redirecionamento de fluxos de dados

LinuxBeginner
Pratique Agora

Introdução

Normalmente, os comandos Linux leem a entrada do terminal e exibem os resultados nele. O shell pode reconectar esses fluxos de dados a arquivos ou a outros comandos. Isso é chamado de redirecionamento e é a base de registros, pipelines, tarefas em segundo plano e scripts de shell.

Neste laboratório, você trabalhará com a entrada padrão, a saída padrão e o erro padrão. Você aprenderá quando > sobrescreve, quando >> acrescenta conteúdo, como 2> e 2>&1 tratam erros, como um pipe transmite dados, como tee exibe e salva a mesma saída e quando /dev/null é útil.

Entenda a entrada, a saída e o erro padrão

Nesta etapa, você criará um pequeno arquivo de entrada e o conectará aos comandos por meio da entrada padrão.

Todo comando começa com três fluxos padrão:

Descritor Nome Conexão padrão
0 entrada padrão, ou stdin teclado
1 saída padrão, ou stdout terminal
2 erro padrão, ou stderr terminal

Crie e acesse um diretório de trabalho:

mkdir -p /home/labex/project/streams-lab
cd /home/labex/project/streams-lab

Crie um arquivo de entrada com três linhas usando um here-document. O shell envia as linhas entre os dois marcadores EOF para o cat, enquanto > salva a saída do cat em input.txt:

cat > input.txt <<'EOF'
alpha
beta
gamma
EOF

Normalmente, cat input.txt recebe um nome de arquivo como argumento. Em vez disso, o operador < conecta o arquivo ao descritor 0, a entrada padrão:

cat < input.txt

Você deverá ver as três linhas. Use o mesmo redirecionamento de entrada com wc -l, que conta linhas:

wc -l < input.txt

A saída deverá ser 3. Como o nome do arquivo não é passado como argumento para wc, somente o número será exibido.

Redirecione e acrescente conteúdo à saída padrão

Nesta etapa, você redirecionará a saída normal de um comando e observará a diferença entre sobrescrever e acrescentar conteúdo.

Verifique se você está no diretório de trabalho dos fluxos:

cd /home/labex/project/streams-lab

O operador > conecta o descritor 1, a saída padrão, a um arquivo. Ele cria o arquivo ou apaga o conteúdo existente antes de escrever:

echo "Stream report" > report.txt
cat report.txt

Execute outra sobrescrita para confirmar que a linha anterior desaparece:

echo "Input lines: 3" > report.txt
cat report.txt

Agora use >>, que abre o destino no modo de acréscimo:

echo "Status: complete" >> report.txt
cat report.txt

O arquivo deverá conter exatamente duas linhas: Input lines: 3, seguida de Status: complete. O shell realiza o redirecionamento antes de iniciar o comando.

Separe a saída padrão do erro padrão

Nesta etapa, você executará um comando que produz tanto uma saída normal quanto um erro e, depois, salvará cada fluxo em um arquivo diferente.

O comando ls a seguir recebe um caminho existente e um caminho inexistente:

cd /home/labex/project/streams-lab
ls -l input.txt missing.txt

A linha que descreve input.txt pertence ao stdout. A mensagem No such file or directory pertence ao stderr. Por padrão, ambas aparecem no terminal, mas são fluxos separados.

Redirecione o descritor 1 com > e o descritor 2 com 2>:

ls -l input.txt missing.txt > listing.log 2> errors.log

O comando ainda retorna um status de saída diferente de zero porque um dos caminhos não existe, mas o shell continua pronto para o próximo comando. Verifique os arquivos de destino:

cat listing.log
cat errors.log

listing.log deverá mencionar input.txt, sem o erro. errors.log deverá mencionar missing.txt e o erro, sem a listagem bem-sucedida.

Combine a saída padrão e o erro padrão

Nesta etapa, você enviará stdout e stderr para um único registro e aprenderá por que a ordem do redirecionamento é importante.

Primeiro, redirecione stdout para combined.log. Em seguida, aponte o descritor 2 para o destino atual do descritor 1:

cd /home/labex/project/streams-lab
ls -l input.txt missing.txt > combined.log 2>&1

A expressão 2>&1 significa “enviar o descritor 2 para o mesmo destino usado atualmente pelo descritor 1”. Como > combined.log aparece primeiro, os dois fluxos chegam ao arquivo.

cat combined.log

O arquivo deverá conter tanto a listagem de input.txt quanto o erro de missing.txt.

O Bash também oferece &> como forma abreviada de redirecionar os dois fluxos:

ls -l report.txt absent.txt &> shorthand.log
cat shorthand.log

Este segundo arquivo deverá conter a listagem bem-sucedida de report.txt e o erro de absent.txt. A forma portátil > file 2>&1 é especialmente comum em scripts e comandos de serviços.

Visualize e salve a saída de um pipeline com tee

Nesta etapa, você usará um pipeline e tee para exibir a saída enquanto salva os mesmos dados em um arquivo.

Um pipe, escrito como |, conecta o stdout do comando à esquerda ao stdin do comando à direita. Ordene o arquivo de entrada em ordem alfabética inversa:

cd /home/labex/project/streams-lab
sort -r input.txt

Com o redirecionamento de saída comum, as linhas ordenadas vão para um arquivo e deixam de aparecer no terminal:

sort -r input.txt > sorted.txt
cat sorted.txt

O comando tee copia seu stdin tanto para o stdout quanto para um arquivo especificado. Execute a mesma ordenação por meio de um pipe:

sort -r input.txt | tee sorted.txt

Você deverá ver as linhas ordenadas na tela, e sorted.txt receberá o mesmo conteúdo. Por padrão, tee sobrescreve o destino, assim como >.

A opção -a faz o tee acrescentar conteúdo. Adicione mais uma linha enquanto a exibe:

echo "delta" | tee -a sorted.txt
cat sorted.txt

O arquivo deverá conter agora gamma, beta, alpha e delta. tee é útil quando você precisa acompanhar a saída no terminal e salvar um registro ao mesmo tempo.

Descarte dados desnecessários com Dev Null

Nesta etapa, você descartará intencionalmente um fluxo com /dev/null, preservará a saída útil com tee e esvaziará um registro existente.

/dev/null é um dispositivo especial que aceita e descarta tudo o que é gravado nele. Liste um diretório real e um diretório inexistente, descartando apenas o stderr:

cd /home/labex/project/streams-lab
ls -l . missing-directory 2> /dev/null

Você deverá ver a listagem do diretório, mas nenhuma mensagem de erro sobre missing-directory. Combine isso com tee para que o stdout visível também seja salvo:

ls -l . missing-directory 2> /dev/null | tee visible-listing.log

O pipe transporta apenas o stdout. O stderr foi redirecionado separadamente para /dev/null antes que o pipe recebesse os dados.

Verifique a listagem salva:

cat visible-listing.log

Por fim, crie um registro temporário descartável e use /dev/null como fonte de entrada vazia para limpar seu conteúdo. Um arquivo separado preserva as evidências do fluxo combinado da Etapa 4:

echo "outdated scratch data" > scratch.log
cat /dev/null > scratch.log

Verifique o tamanho do arquivo:

ls -l scratch.log

O arquivo ainda deverá existir com tamanho de 0 bytes. Use o descarte de forma deliberada: erros ocultos podem dificultar a solução de problemas quando você realmente precisa de informações de diagnóstico.

Resumo

Você praticou o uso dos três fluxos padrão e de seus descritores de arquivo, conectou arquivos ao stdin com < e redirecionou o stdout com > e >>. Você separou o stderr com 2>, combinou-o com o stdout usando 2>&1 e &> e aprendeu por que a ordem dos operadores é importante.

Você também comparou o redirecionamento comum para arquivos com pipelines e tee, usou tee -a para acrescentar conteúdo enquanto exibia a saída e descartou dados desnecessários com /dev/null. Esses padrões ajudarão você a entender registros, comandos em segundo plano e scripts de shell mais adiante no curso.