A pergunta no atual aviso de recompensa:
o exemplo geral é muito complicado. Alguém pode explicar como implementar o exemplo a seguir?diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
parece ter uma resposta aqui .
Conforme mostrado na resposta de Gilles , a idéia geral é enviar a saída dos comandos "produtor" para os novos arquivos de dispositivo 1 em diferentes estágios de um pipeline, disponibilizando-os para os comandos "consumidor", que podem ter nomes de arquivos como argumentos ( assumindo que seu sistema lhe dá acesso aos descritores de arquivos como /dev/fd/X
).
A maneira mais simples de conseguir o que você está procurando é provavelmente:
xz -cd file1.xz | { xz -cd file2.xz | diff /dev/fd/3 -; } 3<&0
(Usando file1.xz
no lugar de "$1"
legibilidade e em xz -cd
vez de cat ... | xz -d
porque um único comando é suficiente).
A saída do primeiro comando "produtor" xz -cd file1.xz
,, é canalizada para um comando composto ( {...}
); mas, em vez de ser consumido imediatamente como entrada padrão do próximo comando, ele é duplicado para o descritor de arquivo 3
e, portanto, tornado acessível a tudo dentro do comando composto como /dev/fd/3
. A saída do segundo comando "produtor" xz -cd file2.xz
, que não consome sua entrada padrão nem nada do descritor de arquivo 3
, é canalizada para o comando "consumidor" diff
, que lê sua entrada padrão e de /dev/fd/3
.
A duplicação de tubulação e descritor de arquivo pode ser adicionada para fornecer arquivos de dispositivo para quantos comandos "produtor" forem necessários, por exemplo:
xz -cd file1.xz | { xz -cd file2.xz | { diff /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
Embora possa ser irrelevante no contexto de sua pergunta específica, vale a pena notar que:
cmd1 <(cmd2) <(cmd3)
, cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
E ( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )
têm diferentes potenciais efeitos sobre o ambiente de execução inicial.
Ao contrário do que acontece na cmd1 <(cmd2) <(cmd3)
, cmd3
e cmd1
em cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
não vai ser capaz de ler qualquer entrada do usuário. Isso exigirá mais descritores de arquivo. Por exemplo, para combinar
diff <(echo foo) <(read var; echo "$var")
você vai precisar de algo como
{ echo foo | { read var 0<&9; echo "$var" | diff /dev/fd/3 -; } 3<&0; } 9<&0
1 Mais sobre eles podem ser encontrados em U&L, por exemplo, em Entendendo / dev e seus subdiretórios e arquivos .