Однорядковий файл з 2 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
2-я версія більш чітко нагадає, який саме вхід був, показуючи
-- /dev/stdin
порівняно ++ /dev/fd/63
чи щось замість двох пронумерованих fds.
Навіть названа труба не з’явиться у файловій системі, принаймні на ОС, де 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)'
Без удару ви можете зробити названу трубу . Використовуйте, -
щоб сказати, 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
mkfifo a; cmd >a& cmd2|diff a -; rm a