Однострочный файл с двумя tmp (не то, что вы хотите) будет:
foo | bar > file1.txt && baz | quux > file2.txt && diff file1.txt file2.txt
Однако с помощью bash вы можете попробовать:
diff <(foo | bar) <(baz | quux)
foo | bar | diff - <(baz | quux) # or only use process substitution once
Вторая версия более четко напомнит вам, какой вход был какой, показывая
-- /dev/stdin vs. ++ /dev/fd/63 или что-то в этом роде, вместо двух пронумерованных файловых файлов.
В файловой системе не появится даже именованный канал, по крайней мере, в операционных системах, где bash может реализовать подстановку процессов, используя имена файлов, такие как /dev/fd/63, чтобы получить имя файла, которое команда может открыть и прочитать, чтобы фактически прочитать из уже открытого файлового дескриптора, который bash настроить перед выполнением команды. (т.е. bash использует pipe(2) перед fork, а затем dup2 для перенаправления с вывода quux на дескриптор входного файла для diff на fd 63.)
В системе без «волшебных» /dev/fd или /proc/self/fd bash может использовать именованные каналы для реализации подстановки процессов, но он, по крайней мере, сам будет управлять ими, в отличие от временных файлов, и ваши данные не будут записаны в файловую систему.
Вы можете проверить, как bash реализует подстановку процесса с помощью echo <(true), чтобы напечатать имя файла вместо чтения из него. Он печатает /dev/fd/63 в типичной системе Linux. Или для получения более подробной информации о том, какие именно системные вызовы использует bash, эта команда в системе Linux будет отслеживать системные вызовы файлов и файловых дескрипторов.
strace -f -efile,desc,clone,execve bash -c '/bin/true | diff -u - <(/bin/true)'
Без bash можно было бы создать именованный канал. Используйте -, чтобы указать diff читать один ввод из STDIN и использовать именованный канал в качестве другого:
mkfifo file1_pipe.txt
foo|bar > file1_pipe.txt && baz | quux | diff file1_pipe.txt - && rm file1_pipe.txt
Обратите внимание, что с помощью команды tee вы можете перенаправить только один выход на несколько входов:
ls *.txt | tee /dev/tty txtlist.txt
Приведенная выше команда отображает вывод ls * .txt на терминал и выводит его в текстовый файл txtlist.txt.
Но с подстановкой процесса вы можете использовать tee для передачи одних и тех же данных в несколько конвейеров:
cat *.txt | tee >(foo | bar > result1.txt) >(baz | quux > result2.txt) | foobar
person
VonC
schedule
05.12.2008