Em bash
, posso usar a Substituição de Processo e tratar a saída de um processo como se fosse um arquivo salvo no disco:
$ echo <(ls)
/dev/fd/63
$ ls -lAhF <(ls)
lr-x------ 1 root root 64 Sep 17 12:55 /dev/fd/63 -> pipe:[1652825]
infelizmente, a Substituição de Processo não é suportada no dash
.
Qual seria a melhor maneira de emular Process Substitution
em hífen?
Não quero salvar a saída como um arquivo temporário em algum lugar ( /tmp/
) e, em seguida, tenho que excluí-la. Existe uma maneira alternativa?
process-substitution
dash
Martin Vegter
fonte
fonte
bash
no seu dispositivo?/dev/fd
e usando emxz -cd <file>
vez decat <file> | xz -d
) poderia serxz -cd "$1" | { xz -cd "$2" | { diff /dev/fd/3 /dev/fd/4; } 3<&0; } 4<&0
.Respostas:
A pergunta no atual aviso de recompensa:
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:
(Usando
file1.xz
no lugar de"$1"
legibilidade e emxz -cd
vez decat ... | 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 arquivo3
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 arquivo3
, é 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:
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
ecmd1
emcmd2 | { 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 combinarvocê vai precisar de algo como
1 Mais sobre eles podem ser encontrados em U&L, por exemplo, em Entendendo / dev e seus subdiretórios e arquivos .
fonte
Você pode reproduzir o que a concha faz sob o capô, fazendo o encanamento manualmente. Se o seu sistema tiver entradas, você pode usar a desarmação de descritores de arquivos: você pode traduzir
/dev/fd/NNN
para
Eu mostrei um exemplo mais complexo para ilustrar várias entradas e saídas. Se você não precisar ler da entrada padrão, e o único motivo pelo qual você está usando a substituição do processo é que o comando requer um nome explícito de arquivo, você pode simplesmente usar
/dev/stdin
:Sem , você precisa usar um pipe nomeado . Um pipe nomeado é uma entrada de diretório, portanto, você precisa criar um arquivo temporário em algum lugar, mas esse arquivo é apenas um nome, não contém dados.
/dev/fd/NNN
fonte
</dev/fd/8 >/dev/fd/9
não são equivalentes<&8 >&9
no Linux e devem ser evitados lá.diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
:?Eu acho que pipes nomeados são mais fáceis de grok do que redirecionamentos, portanto, em termos mais simples:
p1
ep2
são pipes nomeados temporários, eles podem ter qualquer nome.Seria mais inteligente criar os pipes
/tmp
, por exemplo, em um diretório, como mostra a resposta de Gilles , e observe que você não precisacat
aqui, portanto:(Você também pode fugir sem as aspas, pois
mktemp
é provável que crie nomes de arquivos "agradáveis".)A solução de tubulação tem a ressalva de que, se o comando principal (
diff
) morrer antes de ler todas as entradas, os processos em segundo plano poderão ser interrompidos.fonte
A respeito:
fonte