Una riga con 2 file tmp (non quello che vuoi) sarebbe:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Con bash , potresti provare però:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
La seconda versione ti ricorderà più chiaramente quale input era, mostrando
-- /dev/stdin
contro ++ /dev/fd/63
o qualcosa del genere, invece di due fds numerati.
Nemmeno una pipa con nome apparirà nel filesystem, almeno sui sistemi operativi in cui bash può implementare la sostituzione di processo usando nomi di file come /dev/fd/63
ottenere un nome file da cui il comando può aprire e leggere per leggere effettivamente da un descrittore di file già aperto che Bash imposta prima di eseguire il comando. (cioè bash usa pipe(2)
prima di fork, e poi dup2
per reindirizzare dall'output di quux
a un descrittore di file di input per diff
, su fd 63.)
Su un sistema senza "magico" /dev/fd
o /proc/self/fd
, bash potrebbe usare named pipe per implementare la sostituzione dei processi, ma almeno li gestirà da solo, diversamente dai file temporanei, e i tuoi dati non verrebbero scritti nel filesystem.
Puoi controllare come bash implementa la sostituzione del processo echo <(true)
per stampare il nome del file invece di leggerlo. Stampa /dev/fd/63
su un tipico sistema Linux. O per maggiori dettagli su ciò che il sistema chiama bash, questo comando su un sistema Linux traccerà le chiamate di sistema con descrittori di file
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Senza bash, potresti creare una pipa denominata . Utilizzare -
per dire diff
di leggere un input da STDIN e utilizzare la pipe denominata come l'altro:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Si noti che è possibile reindirizzare solo un'uscita a più ingressi con il comando tee:
ls *.txt | tee /dev/tty txtlist.txt
Il comando sopra mostra l'output di ls * .txt sul terminale e lo invia al file di testo txtlist.txt.
Ma con la sostituzione del processo, è possibile utilizzare tee
per inserire gli stessi dati in più pipeline:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a