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.
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
.
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).