Jednowierszowy z 2 plikami tmp (nie tym, czego chcesz) byłby:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
W przypadku basha możesz jednak spróbować:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
Druga wersja będzie wyraźniej przypominać ci, które wejście było które, pokazując
-- /dev/stdinvs. ++ /dev/fd/63lub coś, zamiast dwóch ponumerowanych fds.
Nawet nazwany potok nie pojawi się w systemie plików, przynajmniej w systemach operacyjnych, w których bash może zaimplementować podstawianie procesów przy użyciu nazw plików, takich jak /dev/fd/63uzyskanie nazwy pliku, którą polecenie może otworzyć i odczytać, aby faktycznie czytać z już otwartego deskryptora pliku ustawionego przez bash up przed wykonaniem polecenia. (tj. bash używa pipe(2)przed rozwidleniem, a następnie dup2przekierowuje z wyjścia quuxdo deskryptora pliku wejściowego dla diff, na fd 63.)
W systemie bez "magicznych" /dev/fdlub /proc/self/fd, bash może używać nazwanych potoków do implementacji podstawiania procesów, ale przynajmniej sam zarządzałby nimi, w przeciwieństwie do plików tymczasowych, a twoje dane nie zostałyby zapisane w systemie plików.
Możesz sprawdzić, jak bash implementuje podstawianie za pomocą, echo <(true)aby wypisać nazwę pliku zamiast czytać z niego. Drukuje /dev/fd/63na typowym systemie Linux. Aby uzyskać więcej informacji na temat dokładnie tego, jakich wywołań systemowych używa bash, to polecenie w systemie Linux będzie śledzić wywołania systemowe plików i deskryptorów plików
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Bez basha możesz stworzyć nazwaną potokę . Służy -do mówienia, diffaby odczytać jedno wejście ze STDIN i użyj nazwanego potoku jako drugiego:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Zauważ, że możesz przesłać tylko jedno wyjście do wielu wejść za pomocą polecenia tee:
ls *.txt | tee /dev/tty txtlist.txt
Powyższe polecenie wyświetla wyjście ls * .txt na terminal i wyprowadza je do pliku tekstowego txtlist.txt.
Ale dzięki podstawianiu procesów możesz użyć teedo wprowadzenia tych samych danych do wielu potoków:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
mkfifo a; cmd >a& cmd2|diff a -; rm a