Piping (Canalizando)
O que vamos fazer aqui é, basicamente, pegar as saídas de um lugar e levar para as entradas de outros lugares. Vamos fazer os comandos comunicarem-se, e com isso, faremos coisas mais úteis.
O caractere do pipe é o '|'. O pipe pega a saída do comando da esquerda e joga na entrada do comando da direita.
Exemplo:
cat bin.txt | wc
Sabemos que a saída do
cat bin.txt é mostrar na tela o conteúdo de tal arquivo (você também pode usar
more ou
less).
Porém, ao invés da saída ir para tela, ela vai pro
wc .
Ou seja, nós canalizamos a saída de um comando pra entrada de outro.
Por exemplo, se usar usar
Debian e/ou seus derivadas, baixe o Spell:
sudo apt-get install spell
É um antigo dicionário, usado na época do Unix. Você passa para ele uma lista de palavras, e ele retorna aquelas que não fazem parte do inglês.
Vamos fazer um script que detecte palavras escritas erradas, mas que não mostre as duplicadas adjacentes e as exiba em ordem alfabética.
Não existe um comando que faça tudo isso. Mas vamos pensar como o Unix: existe um comando que coloca as linhas em ordem alfabética -
sort - outro que tira as duplicadas adjacentes -
uniq - e o Spell, pra checar as palavras escritas erradas.
A utilidade do pipeline é deixar estes comandos interagirem, sem termos que escrever vários comandos, com várias saídas e entradas. Veja:
spell bin.txt | sort | uniq > palavras_nao_reconhecidas.txt
5
Chequei os erros, joguei o resultado para ser ordenado, e o resultado disso mandei para ser checado a existência de linhas duplicadas. Ao término de tudo, salvei esta informação em um arquivo de texto.
Este foi apenas um simples exemplo. Não existe limite para o tanto de comandos e nem você é preso aos comandos do sistema, podendo fazer os seus scripts tomarem parte nesta canalização.
Piping em scripts shell
Lembrando que o shell tem input por meio de teclado, através do comando
read, que lê o que o usuário digita e guarda numa variável. Bom, se tem
input, pode ser redirecionado! Tenha esta flexibilidade sempre em mente.
Crie o shell script "pipe.sh":
#!/bin/sh
echo "Digite um numero: "
read NUM
echo "O numero digitado foi $NUM"
Dê permissão para a execução:
chmod +x pipe.sh
Execute com:
echo 10 | ./pipe.sh
Ou seja, canalizamos a saída do
echo pra entrada do seu script.
tee : enviando a saída para mais de um arquivo
Muitas vezes, além de enviar a saída para um arquivo de texto, também queremos ver seu resultado na tela, ou queremos um registro de tudo que ocorreu em nosso terminal, sem afetar seu uso.
O comando
tee tem o seguinte modelo:
comando | tee arquivo1 | tee arquivo2 | tee ... | comando_que_vai_na_tela
Exemplo:
ls /usr/bin | tee bin.txt | tee bin_backup.txt | wc
Assim, faremos duas cópias da lista de arquivos da pasta de executáveis, ao passo que exibe na tela do terminal, um outro comando de seu interesse, no caso o
wc.
Loopings
Para mostrar o poder e perigo dos pipelines, vamos criar um loop.
O conceito de loop é que um script recebe um comando, o executa e chama o próprio arquivo.
Caso conectemos de forma correta a entrada e a saída, o loop ocorrerá indefinidamente.
Exemplo 1
Crie o arquivo "looping" com o seguinte conteúdo:
read COMANDO
$COMANDO
echo $COMANDO | ./looping
Dê permissão de execução:
chmod +x looping
E o execute com o comando
ls. Por exemplo:
echo ls | ./looping
A variável COMANDO se torna 'ls', executa-se (mostrando o conteúdo do diretório), depois invoca-se novamente com o argumento 'ls', e tudo se repete.
Mate o processo: Ctrl+c
Em outros termos, nós conectamos a saída do arquivo a sua entrada e apenas demos o pontapé inicial com o 'ls'.
Exemplo 2
Usaremos aqui o comando
tail, que mostra as últimas linhas de um arquivo.
Com a flag '-f', ele exibe o que foi anexado, à medida que o arquivo cresce. Note este 'à medida o arquivo cresce'.
Crie um arquivo de texto Rush.txt, com qualquer coisa escrita:
Rush!!!
Agora, o nosso comando, que é um pipeline usando o comando
tail:
tail -f Rush.txt >> Rush.txt
Sua saída é direcionada de forma a ser anexada nele mesmo. Porém, como essa anexação é dinâmica, está acontecendo do arquivo para o próprio arquivo, a anexação não para nunca (reflita, não se entende logo não, tem que quebrar a cabeça mesmo, só assim tem graça!).
Portanto, este arquivo cresce indefinidamente e só para quando seu HD lotar.
Para parar o processo: Ctrl+C
Considerações finais
Não há muito o que se falar sobre pipelines. Eles são assim, simples, poderosos e perigosos. Estão acontecendo agora, entre o teclado, mouse, memória, impressora... Eles dividem, para conquistar.
Para usar mais de seus sistemas, você precisa criar pipelines que envolvam processos de seu S.O. Pegando informações, passando, checando erros, testando condições para saber para onde você deve canalizar outra informação... Mas, processos são assuntos para outro artigo.
Artigo criado para a comunidade
Viva o Linux e para o blog
Programação Progressiva.
Jarlisson Moreira