Vamos voltar ao exemplo
dos pipes, já que eles são bastante interessantes e também um bom
exmplo das noções de links. Quando você usa um pipe em uma linha
de comando, o shell
cria o pipe para você e o coloca para
funcionar, então o comando antes do pipe escreve nele e o comando
depois do pipe lê a partir dele. Todos os pipes, quer sejam
anônimos (como aqueles
utilizados pelo shell
) ou nomeados
(veja abaixo) trabalha como FIFOs (First In, First Out -
Primeiro que entra, primeiro que sai). Nós já vimos alguns
exemplos de como usar pipes no shell
, mas vamos dar outra
olhada para o propósito de nossa demonstração:
$ ls -d /proc/[0-9] | head -5 /proc/1/ /proc/2/ /proc/3/ /proc/4/ /proc/5/
Uma coisa que você não vai perceber
neste exemplo (porque ela acontece rápida demais para percebermos)
é que a escrita em pipes é bloqueada. Isto significa que quando o
comando ls escreve no pipe, ele fica bloqueado
até que um processo na outra ponta leia o pipe. Para visualizar
o efeito, você pode criar pipes nomeados, que ao contrário dos
pipes utilizados pelo shell
possuem nomes (ex.:
eles são referenciados, enquanto os pipes do shell
não são)[5]. O comando para criar um pipe nomeado é o mkfifo:
$ mkfifo a_pipe $ ls -il total 0 169 prw-rw-r-- 1 usuario1 usuario1 0 Aug 6 19:37 a_pipe| # # Você pode ver que o contador de link é 1, e que a saída mostra # que o arquivo é um pipe ('p'). # # Você também pode usar o ln aqui: # $ ln a_pipe the_same_pipe $ ls -il total 0 169 prw-rw-r-- 2 usuario1 usuario1 0 Aug 6 19:37 a_pipe| 169 prw-rw-r-- 2 usuario1 usuario1 0 Aug 6 19:37 the_same_pipe| $ ls -d /proc/[0-9] >a_pipe # # O processo está bloqueado, já que não umprocesso para ler na # outra ponta. # Digite Control Z para suspender o processo... # [1]+ Stopped ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe # # ...Então coloque-o em background: # $ bg [1]+ ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe & # # agora leia-o a partir do pipe... # $ head -5 <the_same_pipe # # ...o processo de escrita termina # /proc/1/ /proc/2/ /proc/3/ /proc/4/ /proc/5/ [1]+ Done ls -F --show-control-chars --color=auto -d /proc/[0-9] >a_pipe $
De maneira similar, leituras também estão bloqueadas. Se nós executarmos os comandos acima em ordem reversa, nós veremos que os blocos do head, esperando por algum processo para dar a ele algo para ler:
$ head -5 <a_pipe # # Blocos do programa, suspenso com: C-z # [1]+ Stopped head -5 <a_pipe # # Coloque-o no background... # $ bg [1]+ head -5 <a_pipe & # # ...e alimente-o :) # $ ls -d /proc/[0-9] >the_same_pipe /proc/1/ /proc/2/ /proc/3/ /proc/4/ /proc/5/ [1]+ Done head -5 <a_pipe $
Você também pode constatar um efeito não desejado no exemplo anterior: o comando ls terminou antes que o comando head o pegasse. A consequência disto é que você foi devolvido imediatamente para o prompt, mas o head foi executado depois e você só viu sua saída depois de retornar.