Una línea con 2 archivos tmp (no lo que quieres) sería:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Con bash , puedes intentarlo:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
La segunda versión le recordará más claramente qué entrada fue cuál, mostrando
-- /dev/stdinvs. ++ /dev/fd/63o algo, en lugar de dos fds numerados.
Ni siquiera aparecerá una canalización con nombre en el sistema de archivos, al menos en los sistemas operativos donde bash puede implementar la sustitución de procesos mediante el uso de nombres de archivo como /dev/fd/63para obtener un nombre de archivo que el comando puede abrir y leer para leer realmente desde un descriptor de archivo ya abierto que bash establece antes de ejecutar el comando. (es decir, bash usa pipe(2)antes de fork, y luego dup2para redirigir desde la salida quuxa un descriptor de archivo de entrada para diff, en fd 63.)
En un sistema sin "mágico" /dev/fdo /proc/self/fd, bash podría usar canalizaciones con nombre para implementar la sustitución del proceso, pero al menos las administraría por sí mismo, a diferencia de los archivos temporales, y sus datos no se escribirían en el sistema de archivos.
Puede verificar cómo bash implementa la sustitución de procesos echo <(true)para imprimir el nombre del archivo en lugar de leerlo. Se imprime /dev/fd/63en un sistema Linux típico. O para obtener más detalles sobre exactamente qué llamadas al sistema usa bash, este comando en un sistema Linux rastreará las llamadas al sistema de archivos y descriptores de archivos
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Sin bash, podrías hacer una pipa con nombre . Use -para indicar diffque lea una entrada de STDIN y use la tubería nombrada como la otra:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Tenga en cuenta que solo puede canalizar una salida a múltiples entradas con el comando tee:
ls *.txt | tee /dev/tty txtlist.txt
El comando anterior muestra la salida de ls * .txt al terminal y la envía al archivo de texto txtlist.txt.
Pero con la sustitución de procesos, puede usar teepara alimentar los mismos datos en múltiples canales:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a