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/stdin
vs. ++ /dev/fd/63
o 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/63
para 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 dup2
para redirigir desde la salida quux
a un descriptor de archivo de entrada para diff
, en fd 63.)
En un sistema sin "mágico" /dev/fd
o /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/63
en 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 diff
que 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 tee
para 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