Uma linha com 2 arquivos tmp (não o que você deseja) seria:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Com o bash , você pode tentar:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
A 2ª versão lembrará mais claramente qual entrada foi qual, mostrando
-- /dev/stdin
vs. ++ /dev/fd/63
ou algo assim, em vez de dois fds numerados.
Nem mesmo um pipe nomeado aparecerá no sistema de arquivos, pelo menos nos sistemas operacionais em que o bash pode implementar a substituição do processo usando nomes de arquivos como /dev/fd/63
obter um nome de arquivo que o comando possa abrir e ler para ler de fato um descritor de arquivo já aberto que o bash define antes de executar o comando. (ou seja, o bash usa pipe(2)
antes do fork e, em seguida, dup2
redireciona da saída de quux
para um descritor de arquivo de entrada para diff
, no fd 63.)
Em um sistema sem "mágico" /dev/fd
ou /proc/self/fd
, o bash pode usar pipes nomeados para implementar a substituição do processo, mas pelo menos os gerenciaria, diferentemente dos arquivos temporários, e seus dados não seriam gravados no sistema de arquivos.
Você pode verificar como o bash implementa a substituição do processo echo <(true)
para imprimir o nome do arquivo em vez de lê-lo. Imprime /dev/fd/63
em um sistema Linux típico. Ou, para obter mais detalhes sobre exatamente o que o sistema chama o bash usa, esse comando em um sistema Linux rastreia as chamadas de sistema de descritores de arquivos e arquivos.
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Sem o bash, você poderia fazer um pipe nomeado . Use -
para dizer diff
para ler uma entrada de STDIN e use o pipe nomeado como o outro:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Observe que você pode canalizar apenas uma saída para várias entradas com o comando tee:
ls *.txt | tee /dev/tty txtlist.txt
O comando acima exibe a saída de ls * .txt no terminal e a envia para o arquivo de texto txtlist.txt.
Mas com a substituição do processo, você pode usar tee
para alimentar os mesmos dados em vários pipelines:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a