Encanamento ou piping. Você sabe usar?

Encanamento ou “Piping” é uma técnica que permite conectar a saída de um comando a entrada de outro, de forma que você não precise que todas as ferramentas repliquem as mesmas funcionalidades. Mas você conhece na prática como usar ?

O encanamento é o que ratifica parte da “filosofia Unix”, então antes de seguirmos vamos conhece-la.

Filosofia Unix

A filosofia Unix é uma das heranças que o Linux recebeu do Unix e ela possui alguns dos conceitos mais importantes no desenvolvimento de ferramentas para estes ambientes.

Embora ela não seja uma regra, convencionou-se como tal, possuindo um conjunto de recomendações que eram (e ainda hoje são) seguidas por milhares de desenvolvedores de ferramentas para linha de comandos.

Dentre as mais famosas estão:

  • KISS – “Mantenha isso simples e estúpido” (existem outras variações e significados mas este é mais comum)
  • “Faça uma coisa só, mas faça bem feita”
  • “Trabalhe em conjunto”

Há muitas outras frases de efeito como essas que resumem o estilo do desenvolvimento nestes ambientes, mas para o nosso objetivo vamos nos prender a estes três apenas pois é aqui que o nosso “piping” se enquadra.

Piping ou encanamento

O “piping” é feito com o caractere de linha vertical “|”. Imagino que a ideia de usá-lo é justamente porque ele passa a ideia de um “cano” que conecte duas pontas (lembre-se que estamos falando de um conceito que remonta os anos 1960 então possivelmente este era o símbolo mais perfeito que se podia obter na época).

Para exemplificar vamos pegar dois comandos bem conhecidos. O comando “cat”, usado para mostrar o conteúdo de arquivos e o comando “ls”, que lista o conteúdo de um diretório.

Agora vamos apenas supor (já que não é o caso) que estas ferramentas sigam de fato a filosofia Unix e apenas façam aquilo que se propõe. “ls” apenas lista os arquivos e “cat” apenas mostra o conteúdo de um arquivo.

ls /etc

cat /etc/passwd

O resultado é que temos duas ferramentas muito simples e a vantagem, como já disse, é que os desenvolvedores poderão focar o seu tempo em garantir que cada uma faça isso da melhor maneira possível.

No entanto, é de se esperar que você precise de funcionalidades que não existem ali.

Digamos, por exemplo, que você precise que o conteúdo do arquivo ou a listagem de arquivos sejam exibidas em ordem alfabética, ou mesmo contar quantas linhas foram exibidas, ver a listagem em páginas, já que o conteúdo é grande demais para caber na tela, ou ainda enviar estas saídas por e-mail, guardá-las em um formato comprimido, ou mesmo cifrado com uma senha etc.

As possibilidades do que você queira fazer são infinitas e esperar que o desenvolvedor do “cat”, do “ls” e de todas as demais ferramentas prevejam isso, ou estejam sempre esperando seu pedido por novidades e novos recursos, além de insano – se fosse viável – só deixaria as ferramentas cada mais mais pesadas e com novos bugs.

É aqui que ouvimos então o mantra “mantenhas as coisas simples”, “trabalhe em conjunto”, “faça uma coisa só, mas faça bem feita”. Ao invés de criarmos uma ferramenta entupida de recursos, o mais racional é ter uma outra ferramenta para cada uma daquelas novas atividades e então conecta-las via encanamento.

Se quiséssemos comprimir, temos o gzip. Criptografar? gpg, enviar por e-mail mutt, mail entre outras. Cada uma faz muito bem aquilo que se propôs a fazer e pode ser usada para receber ou enviar dados para outra ferramenta.

No caso de querermos ordenar a saída de qualquer comando bastaria então conectar o comando “sort” para receber a saída do primeiro comando.

Tal como o “ls” é bom em “listar arquivos” e o “cat” é ótimo em mostrar o conteúdo de um arquivo. Agora podemos ter o “sort” que é ótimo em ordenar o conteúdo que ele recebe de qualquer comando.

ls /etc | sort

cat /etc/passwd | sort

O desenvolvedor de cada uma destas três ferramentas se dedicam a fazer aquilo que é o essencial delas, sem se preocupar com detalhes extras.

Vários encanamentos

A quantidade de conexões entre comandos é praticamente ilimitada. Você pode conectar quantos quiser, desde que tenha memória suficiente para manter todos os comandos e seus dados residentes durante a execução, mas para os equipamentos atuais estes podem ser valores considerados pequenos e dificilmente isso será um problema.

Observe no exemplo abaixo como listar todos os arquivos de extensão “.conf” ordenados de forma reversa (de Z a A) e ainda com cada linha numerada:

ls *.conf | sort -r | cat -n

Note aqui que além dos comandos em si, nós temos as chaves e parâmetros de cada comando que modificam funcionamento padrão trazendo novas funcionalidades e recursos a cada uma das ferramentas onde foram usados.

Existe uma linha muito tênue entre vantagens e desvantagens disso já que programar estes argumentos é muito chato e traz risco de incluir bugs. Por outro lado, eles dão ao usuário maior flexibilidade no seu trabalho.

Imagine por exemplo que o sort não tivesse a chave “-r”. Para que pudessemos ter a ordenação invertida precisariamos contar mais um comando ali. O “tac” (exatamente o inverso do cat).

ls *.conf | sort | tac | cat -n

Vamos supor ainda que o “ls” nem tivesse a opção de filtrar os arquivos de extensão “.conf”. Teriamos que usar o grep, awk ou outra ferramenta para realizar a filtragem como segue. Com o bônus/ônus de ter que usar as não tão amigáveis regex, ao invés dos simples wildcards:

ls | grep .*conf$ | sort | tac | cat -n

E ainda, piorando a situação. Se o cat também não tivesse o “-n”. Dentre as inúmeras alternativas poderiamos usar o “awk” como segue (imagino que para quem vê pela primeira vez parece algo alienígena)

ls | grep .*conf$ | sort | tac | awk '{ print "\t"FNR" "$0 }'

Com o tempo você perceberá que alguns comandos possuem tantos argumentos, chaves e parâmetros para fazer coisas diferentes que acabam indo contra a “filosofia unix”, como por exemplo o próprio comando “ls” que possui sua forma própria de ordenar arquivos.

Talvez esta tenha sido uma opção desnecessária, na visão dos puristas e radicais defensores da filosofia Unix, mas longe das discussões filosóficas isso acaba sendo bom e facilita muito a vida do sysadmin quando bem empregado.

O que você prefere usar no dia a dia. Aquela última linha de comandos, ou essa aqui:

ls --reverse  *.conf | cat -n

A Penúltima certamente é mais divertida e carregada de genialidade, mas esta última faz exatamente a mesma coisa (de forma mais simples e estúpida) então acho que ao usar esta última alternativa estamos dentro da filosofia do mesmo jeito!

Conclusão

Eu só deixei alguns exemplos simples de uso do pipe, mas como eu disse as possibilidades são infinitas.

Se o leitor souber conciliar os parâmetros e argumentos disponíveis em cada ferramenta, com o recurso de piping, “entrar pelo cano” deixará de ter uma má conotação e se tornará um dos seus melhores aliados no terminal.

Deixe um comentário

O seu endereço de e-mail não será publicado.

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.