Como usar Pipes no Linux

Terminal Linux em um laptop
Fatmawati Achmad Zaenuri / Shutterstock.com

Use os canais do Linux para coreografar como os utilitários de linha de comando colaboram. Simplifique processos complexos e aumente sua produtividade aproveitando uma coleção de comandos independentes e transformando-os em uma equipe obstinada. Nós mostramos como.

Pipes estão em toda parte

Pipes são um dos recursos de linha de comando mais úteis que o Linux e os sistemas operacionais do tipo Unix têm. Os tubos são usados ​​de inúmeras maneiras. Examine qualquer artigo de linha de comando do Linux – em qualquer site, não apenas o nosso – e você verá que os tubos aparecem com mais frequência do que não. Eu revi alguns dos artigos do How-To Geek sobre Linux, e os pipes são usados ​​em todos eles, de uma forma ou de outra.

Os canais do Linux permitem que você execute ações que não são suportadas imediatamente pelo shell . Mas porque a filosofia de design do Linux é ter muitos pequenos utilitários que executam suas funções dedicadas muito bem e sem funcionalidades desnecessárias – o mantra “faça uma coisa e faça bem” – você pode sondar sequências de comandos junto com canais para que a saída de um comando torna-se a entrada de outro. Cada comando que você envia traz seu talento único para a equipe, e logo você descobre que montou um time vencedor.

Um Exemplo Simples

Suponha que temos um diretório cheio de muitos tipos diferentes de arquivos. Queremos saber quantos arquivos de um determinado tipo estão nesse diretório. Existem outras maneiras de fazer isso, mas o objetivo deste exercício é introduzir tubos, então vamos fazer isso com tubos.

Podemos obter uma lista dos arquivos facilmente usando ls:

ls

Coleção de arquivos em um diretório, em uma janela de terminal

Para separar o tipo de arquivo de interesse, usaremos grep. Queremos encontrar arquivos que tenham a palavra “página” em seu nome de arquivo ou extensão de arquivo.

Usaremos o caractere especial do shell “ |” para canalizar a saída lspara grep.

ls | grep "página"

ls -l |  grep "página" em uma janela de terminal

grepimprime linhas que correspondem ao seu padrão de pesquisa . Portanto, isso nos dá uma lista contendo apenas arquivos “.page”.

lista de arquivos de página em uma janela de terminal

Até mesmo este exemplo trivial exibe a funcionalidade de tubos. A saída de lsnão foi enviada para a janela do terminal. Ele foi enviado grepcomo dados para o grepcomando trabalhar. A saída que vemos vem de grep, qual é o último comando nesta cadeia.

Recomendado:  Ganhe um Yeti Tundra 45 Cooler em nosso último sorteio

Estendendo Nossa Cadeia

Vamos começar a estender nossa cadeia de comandos canalizados. Podemos contar os arquivos “.page” adicionando o wccomando. Usaremos a opção -l(contagem de linhas) com wc. Observe que também adicionamos a opção -l(formato longo) a ls. Estaremos usando isso em breve.

ls - | grep "página" | wc -l

ls - |  grep "página" |  wc -l em uma janela de terminal

grepnão é mais o último comando da cadeia, portanto, não vemos sua saída. A saída de grepé alimentada no wccomando. A saída que vemos na janela do terminal é de wc. wcrelata que há 69 arquivos “.page” no diretório.

Vamos estender as coisas novamente. Tiraremos o wccomando da linha de comando e o substituiremos por  awk. Existem nove colunas na saída lscom a opção -l(formato longo). Usaremos awkpara imprimir as colunas cinco, três e nove. Estes são o tamanho, o proprietário e o nome do arquivo.

ls -l | grep "página" | awk '{print $ 5 "" $ 3 "" $ 9}'

ls -l |  grep "página" |  awk '{print $ 5 "" $ 3 "" $ 9}' em uma janela de terminal

Obtemos uma lista dessas colunas, para cada um dos arquivos correspondentes.

Lista de três colunas para cada arquivo correspondente em uma janela de terminal

Agora, passaremos essa saída por meio do sortcomando. Usaremos a -nopção (numérica) para informar sortque a primeira coluna deve ser tratada como números .

ls -l | grep "página" | awk '{print $ 5 "" $ 3 "" $ 9}' | sort -n

ls -l |  grep "página" |  awk '{print $ 5 "" $ 3 "" $ 9}' |  sort -n em uma janela de terminal

A saída agora é classificada em ordem de tamanho de arquivo, com nossa seleção personalizada de três colunas.

Arquivos classificados por tamanho em uma janela de terminal

Adicionando outro comando

Terminaremos adicionando o tailcomando. Diremos a ele para listar apenas as últimas cinco linhas de saída .

ls -l | grep "página" | awk '{print $ 5 "" $ 3 "" $ 9}' | sort -n | cauda -5

ls -l |  grep "página" |  awk '{print $ 5 "" $ 3 "" $ 9}' |  sort -n |  cauda -5 em uma janela de terminal

Isso significa que nosso comando se traduz em algo como “mostre-me os cinco maiores arquivos“ .page ”neste diretório, ordenados por tamanho.” Claro, não há comando para fazer isso, mas usando tubos, criamos o nosso próprio. Poderíamos adicionar este – ou qualquer outro comando longo – como um alias ou função shell para salvar toda a digitação.

Aqui está o resultado:

Cinco maiores arquivos .page listados por ordem de tamanho em uma janela de terminal

Poderíamos inverter a ordem de tamanho adicionando a -ropção (reverso) ao sortcomando e usando em headvez de tail  para escolher as linhas do topo da saída .

ls -l |  grep "página" |  awk '{print $ 5 "" $ 3 "" $ 9}' |  sort -rn |  head -5 em uma janela de terminal

Desta vez, os cinco maiores arquivos “.page” são listados do maior para o menor:

Os cinco maiores arquivos .page listados em ordem reversa de tamanho em uma janela de terminal

Alguns exemplos recentes

Aqui estão dois exemplos interessantes de artigos recentes sobre como fazer.

Alguns comandos, como xargscomando , são projetados para ter entrada canalizada para eles . Esta é uma maneira de  wc contar as  palavras, caracteres e linhas  em vários arquivos, canalizando lspara o xargsqual alimenta a lista de nomes de arquivos wccomo se tivessem sido passados wccomo parâmetros de linha de comando.

ls * .page | xargs wc

ls * .page |  xargs wc em uma janela de terminal

O número total de palavras, caracteres e linhas são listados na parte inferior da janela do terminal.

Recomendado:  Como compartilhar temporariamente sua localização com alguém usando o Google Maps

Contagem de palavras, caracteres e linhas em uma janela de terminal

Esta é uma maneira de obter uma lista classificada das extensões de arquivo exclusivas no diretório atual, com uma contagem de cada tipo.

ls | rev | cut -d '.' -f1 | rev | classificar | uniq -c

ls |  rev |  cut -d '.'  -f1 |  rev |  classificar |  uniq -c em uma janela de terminal

Há muita coisa acontecendo aqui.

  • ls : Lista os arquivos no diretório
  • rev : Inverte o texto nos nomes dos arquivos.
  • cut : Corta a string na primeira ocorrência do delimitador especificado “.”. O texto depois disso é descartado.
  • rev : Reverte o texto restante , que é a extensão do nome do arquivo.
  • classificar : classifica a lista em ordem alfabética.
  • uniq : conta o número de cada entrada única na lista .

A saída mostra a lista de extensões de arquivo, classificadas em ordem alfabética com uma contagem de cada tipo exclusivo.

Lista de extensões de arquivo exclusivas em uma janela de terminal

Pipes nomeados

Há outro tipo de tubo disponível para nós, chamado de tubos nomeados. Os canais nos exemplos anteriores são criados instantaneamente pelo shell quando ele processa a linha de comando. Os tubos são criados, usados ​​e, em seguida, descartados. Eles são transitórios e não deixam rastros de si mesmos. Eles existem apenas enquanto o comando que os utiliza estiver em execução.

Pipes nomeados aparecem como objetos persistentes no sistema de arquivos, para que você possa vê-los usando ls. Eles são persistentes porque sobreviverão a uma reinicialização do computador – embora todos os dados não lidos neles naquele momento sejam descartados.

Pipes nomeados foram usados ​​muito ao mesmo tempo para permitir que diferentes processos enviassem e recebessem dados, mas eu não os via usados ​​dessa forma há muito tempo. Sem dúvida, existem pessoas por aí que ainda os usam com grande efeito, mas não encontrei nenhum recentemente. Mas para fins de completude, ou apenas para satisfazer sua curiosidade, veja como você pode usá-los.

Pipes nomeados são criados com o mkfifocomando. Este comando criará um pipe nomeado chamado “geek-pipe” no diretório atual.

mkfifo geek-pipe

mkfifo geek-pipe em uma janela de terminal

Podemos ver os detalhes do pipe nomeado se usarmos o lscomando com a opção -l(formato longo):

ls -l geek-pipe

ls -l geek-pipe em uma janela de terminal

O primeiro caractere da lista é um “p”, o que significa que é uma barra vertical. Se fosse um “d”, significaria que o objeto do sistema de arquivos é um diretório e um traço “-” significaria que é um arquivo normal.

Usando o Pipe Nomeado

Vamos usar nosso cachimbo. Os canais não nomeados que usamos em nossos exemplos anteriores transmitiram os dados imediatamente do comando de envio para o comando de recebimento. Os dados enviados por meio de um canal nomeado permanecerão no canal até que sejam lidos. Os dados são mantidos na memória, portanto, o tamanho do canal nomeado não variará nas lslistagens, quer haja dados nele ou não.

Recomendado:  Como definir seu gerenciador de preenchimento automático preferido no Android Oreo

Vamos usar duas janelas de terminal para este exemplo. Vou usar o rótulo:

# Terminal 1

em uma janela de terminal e

# Terminal 2

no outro, para diferenciá-los. O hash “#” diz ao shell que o que se segue é um comentário e deve ser ignorado.

Vamos pegar todo o nosso exemplo anterior e redirecioná-lo para o canal nomeado. Portanto, estamos usando canais não nomeados e nomeados em um comando:

ls | rev | cut -d '.' -f1 | rev | classificar | uniq -c> geek-pipe

ls |  rev |  cut -d '.'  -f1 |  rev |  classificar |  uniq -c> geek-pipe em uma janela de terminal

Nada mais parecerá acontecer. Você pode notar que não retorna ao prompt de comando, então algo está acontecendo.

Na outra janela do terminal, emita este comando:

gato <geek-pipe

cat <geek-pipe em uma janela de terminal

Estamos redirecionando o conteúdo do pipe nomeado para cat, de modo que catexibirá esse conteúdo na segunda janela do terminal. Aqui está o resultado:

O conteúdo do piped nomeado mostrado em uma janela de terminal

E você verá que voltou ao prompt de comando na primeira janela do terminal.

Tarefa concluída e o prompt de comando em uma janela de terminal

Então, o que aconteceu.

  • Redirecionamos alguma saída para o pipe nomeado.
  • A primeira janela do terminal não retornou ao prompt de comando.
  • Os dados permaneceram no tubo até serem lidos no tubo no segundo terminal.
  • Voltamos ao prompt de comando na primeira janela do terminal.

Você pode estar pensando que poderia executar o comando na primeira janela do terminal como uma tarefa em segundo plano, adicionando um &ao final do comando. E você estaria certo. Nesse caso, teríamos retornado ao prompt de comando imediatamente.

O objetivo de não usar processamento em segundo plano era destacar que um pipe nomeado é um processo de bloqueio . Colocar algo em um tubo nomeado abre apenas uma das extremidades do tubo. A outra extremidade não é aberta até que o programa de leitura extraia os dados. O kernel suspende o processo na primeira janela do terminal até que os dados sejam lidos da outra extremidade do tubo.

O poder dos tubos

Hoje em dia, cachimbos nomeados são uma espécie de novidade.

Canais simples e antigos do Linux, por outro lado, são uma das ferramentas mais úteis que você pode ter em seu kit de ferramentas de janela de terminal. A linha de comando do Linux começa a ganhar vida para você, e você ganha um novo poder quando pode orquestrar uma coleção de comandos para produzir um desempenho coeso.

Dica de despedida: É melhor escrever seus comandos canalizados adicionando um comando de cada vez e fazendo com que essa parte funcione e, em seguida, canalizando o próximo comando.