4. Redirecionamentos e Pipes

4.1. Um Pouco Mais Sobre Processos

Para compreender o princípio dos redirecionamentos e pipes precisamos explicar uma noção a respeito de processo que ainda não foi apresentada. A maioria dos processos UNIX® (incluindo também as aplicações gráficas mas exclui a maioria dos daemons) usam um mínimo de três descritores de arquivo: entrada padrão, saída padrão e saída de erro padrão. Seus números respectivos são 0, 1 e 2. Em geral, esses três descritores estão associados com o terminal no qual o processo foi iniciado, com a entrada sendo a partir do teclado. O objetivo de redirecionamentos e pipes é para redirecionar esses descritores. Os exemplos nesta seção irão ajudá-lo a compreender melhor esse conceito.

4.2. Redirecionamentos

Imagine, por exemplo, que você quer uma lista de arquivos que terminem em .png[15] no diretório images. Essa lista é muito grande, então você quer armazená-la em um arquivo para vê-la com mais calma mais tarde. Você pode digitar o seguinte comando:

$ ls images/*.png 1>file_list

A saída padrão desse comando (1) é redirecionada (>) para o arquivo com nome file_list. O operador > é o operador de redirecionamento de saída. Se o arquivo para o qual o redirecionamento foi apontado não existir, ele é criado, mas, se ele já existir, seu conteúdo anterior é sobrescrito. Entretanto, o descritor padrão, redirecionado pelo operador é o descritor da saída padrão e não necessita ser especificado na linha de comando. Então, podemos simplesmente escrever:

$ ls images/*.png >file_list

e o resultado será exatamente o mesmo. Então, a seguir você pode analisar o conteúdo do arquivo utilizando um visualizador de arquivos como o comando less.

Agora, imagine que você quer saber quantos desses arquivos existem. Ao invés de contá-los manualmente, você pode usar o utilitário chamado wc (Contador de Palavras - Word Count) com a opção -l, que escreve na saída padrão o número de linhas no arquivo. Uma solução é a seguinte:

$ wc -l 0<file_list

e esse comando irá retornar o resultado desejado. O operador < é o operador de redirecionamento de entrada, e o descritor redirecionado por padrão é a entrada padrão, i.e. 0, e você simplesmente precisa escrever a seguinte linha de comando:

$ wc -l <file_list

Agora imagine que você quer remover todas as “extensões” de arquivo e colocar o resultado em um outro arquivo. Uma ferramenta para fazer isso é o comando sed (Editor de Fluxos - Stream EDitor). Você simplesmente redireciona a entrada padrão do comando sed para o arquivo file_list e redireciona sua saída para o arquivo de resultados, i.e. the_list:

$ sed -e 's/\.png$//g' <file_list >the_list

e a sua lista está criada, pronta para ser vista com qualquer visualizador a qualquer hora.

Pode ser útil também redirecionar a saída padrão de erros. Por exemplo, você quer saber em quais diretórios abaixo do diretório /shared você não consegue acessar: uma solução é listar o diretório recursivamente e redirecionar os erros para um arquivo, enquanto não mostra na saída padrão:

$ ls -R /shared >/dev/null 2>errors

a saída padrão será redirecionada (>) para /dev/null, um arquivo especial no qual, qualquer coisa que seja escrita nele será descartada (i.e. a saída padrão não é mostrada) e a saída de erros padrão (2) é redirecionada (>) para o arquivo errors .

4.3. Pipes

Os "pipes" (termo em inglês) são, de algumas maneiras uma combinação dos redirecionamentos de entrada e saída padrão. O princípio é como se fosse um cano físico, daí o nome (pipe é cano em inglês): um processo envia dados em uma ponta do pipe e o outro processo lê os dados na outra ponta. O operador pipe é representado pelo caractere |. Voltemos então ao exemplo anterior, o da lista de arquivos. Suponha que você quer encontrar diretamente quantos arquivos existem no diretório, sem armazenar a lista em um arquivo temporário. Para executar essa ação, digite o seguinte comando:

$ ls images/*.png | wc -l

que irá passar a saída padrão do comando ls (i.e. a lista dos arquivos) redirecionando-a para a entrada padrão do comando wc. Esse comando dará o resultado esperado.

Você também pode gerar um arquivo de saída com uma lista de nomes de arquivo “sem extensões” utilizando o seguinte comando:

$ ls images/*.png | sed -e 's/\.png$//g' >the_list

ou, se você quiser visualizar a lista diretamente, sem armazená-la em um arquivo:

$ ls images/*.png | sed -e 's/\.png$//g' | less

Os pipes e redirecionamentos não estão restritos somente a texto legível. Por exemplo, o seguinte comando digitado a partir de um Terminal:

$ xwd -root | convert - ~/my_desktop.png

irá gravar uma foto da tela no arquivo my_desktop.png [16] no seu diretório pessoal.



[15] Você pode pensar que é loucura dizer “arquivos terminados em .png” ao invés de “imagens PNG”. Entretanto, mais uma vez, os arquivos sob o UNIX® somente tem uma extensão por convenção: as extensões não são, de maneira alguma, uma forma de definir um tipo de arquivo. Um arquivo cujo nome termine em .png pode perfeitamente ser uma imagem JPEG, um arquivo de uma aplicação, um arquivo texto ou qualquer outro tipo de arquivo. O mesmo é verdade sob Windows®!

[16] sim, ele realmente será uma imagem PNG (de qualquer maneira, o pacote ImageMagick precisa estar instalado para executar esse comando).