Две трубы к одной команде

9

Меня немного смущает следующий синтаксис. Хотя это работает, он не понимает, почему это работает. Кажется, что к команде diff прикреплены две трубы. Но разве не один STDIN?

Примеры:

diff <(echo "foobar") <(echo "barbaz")
diff <(cat foo.txt) <(cat bar.txt)
iblue
источник
Вот ссылка на соответствующую тему - процесс замены - на bashстранице руководства .
chepner

Ответы:

13

Каналы просто связаны с дескрипторами файлов, отличными от 0 (stdin):

$ echo <(true)
/dev/fd/63
$ echo <(true) <(true)
/dev/fd/63 /dev/fd/62

Конечно, процесс может иметь более одного дескриптора открытого файла одновременно, поэтому проблем нет.

Свен Марнах
источник
Если бы я знал только его временные каналы, я бы смог их погуглить. Спасибо!
@iblue: Я не думаю, что это называется "временные трубы". Это просто каналы, созданные pipe()системным вызовом.
Свен Марнах
Чтобы быть очень точным, это можно назвать «анонимными именованными каналами», но этого достаточно, чтобы погуглить.
2
@WilliamPursell: Нет вовлеченных файлов. Оболочка создает анонимный канал с использованием pipe()и затем разветвляет подпроцессы. Основной процесс делает иметь дополнительные дескрипторы открыть , если используются анонимная труба. Эти дополнительные файловые дескрипторы передаются в форме /dev/fd/..., и процесс обычно просто открывает их, используя эти имена файлов. Это приведет к их dup()редактированию, создавая еще больше открытых файловых дескрипторов. Процесс также может сразу использовать именованный дескриптор файла без каких-либо открытых вызовов ...
Свен Марнах
1
... как продемонстрировано в этой маленькой и глупой тестовой программе . После компиляции в a, я назвал его как ./a <(ls), и он успешно распечатал список файлов, доказав, что названный файловый дескриптор (63 в моем случае) уже был открыт. Bash может использовать именованные каналы во временном каталоге на архитектурах, отличных от Linux, и в этом случае никакие дополнительные файловые дескрипторы не будут открываться при входе в основной процесс.
Свен Марнач