Substituição de Processos
Colaboração: Julio Cezar Neves
Data de Publicação: 22 de Fevereiro de 2005
Hoje vou mostrar que o Shell também usa os named pipes de uma maneira bastante
singular, que é a substituição de processos (process substitution). Uma
substituição de processos ocorre quando você põe um <
ou um >
grudado na
frente do parêntese da esquerda. Teclando-se o comando:
$ cat <(ls -l)
Resultará no comando ls -l
executado em um subshell como
é normal, porém redirecionará a saída para um named pipe
temporário, que o Shell cria, nomeia e depois remove. Então
o cat
terá um nome de arquivo válido para ler (que será este
named pipe e cujo dispositivo lógico associado é /dev/fd/63
),
e teremos a mesma saída que a gerada pela listagem do ls -l
,
porém dando um ou mais passos que o usual.
Como poderemos constatar isso? Fácil... Veja o comando a seguir:
$ ls -l >(cat)
l-wx------ 1 jneves jneves 64 Aug 27 12:26 /dev/fd/63 -> pipe:[7050]
É... Realmente é um named pipe.
Você deve estar pensando que isto é uma maluquice de nerd,
né? Então suponha que você tenha 2 diretórios: dir
e dir.bkp
e deseja saber se os dois estão iguais (aquela velha dúvida:
será que meu backup está atualizado?). Basta comparar os dados
dos arquivos dos diretórios com o comando cmp
, fazendo:
$ cmp <(cat dir/*) <(cat dir.bkp/*) || echo backup furado
ou, melhor ainda:
$ cmp <(cat dir/*) <(cat dir.bkp/*) >/dev/null || echo backup furado
Este é um exemplo meramente didático, mas são tantos os comandos que produzem mais de uma linha de saída, que serve como guia para outros. Eu quero gerar uma listagem dos meus arquivos, numerando-os e ao final dar o total de arquivos do diretório corrente:
while read arq do ((i++)) # assim nao eh necessario inicializar i echo "$i: $arq" done < <(ls) echo "No diretorio corrente (`pwd`) existem $i arquivos"
Tá legal, eu sei que existem outras formas de executar a mesma
tarefa. Mas tente fazer usando while
, sem usar substituição
de processos que você verá que este método é muito melhor.