Перенаправление двух файлов на стандартный вход

Существует несколько команд unix, которые предназначены для работы с двумя файлами. Обычно такие команды позволяют считывать содержимое для одного из "файлов" со стандартного ввода с помощью одной тире вместо имени файла.

Я только что наткнулся на технику, которая позволяет читать оба файла со стандартного ввода:

comm -12 <(sort file1) <(sort file2)

Моя первоначальная неверная реакция заключалась в том, что "это не должно работать. Стандартный ввод будет иметь только объединение двух файлов. Команда не сможет рассказать файлы отдельно или даже понять, что ей было предоставлено содержимое два файла."

Конечно, эта конструкция действительно работает. Я тестировал его с помощью comm и diff, используя bash 3.2.51 на cygwin 1.7.7. Мне любопытно, как и почему это работает:

  • Почему это работает?
  • Это расширение bash, или это прямая функциональность оболочки Bourne?
  • Это работает в моей системе, но будет ли эта техника работать на других платформах? (Другими словами, скрипты, написанные с использованием этой техники, будут переносимыми?)

Ответ 1

Bash, оболочка Korn (ksh93, в любом случае) и Z-оболочка поддерживают замещение процесса. Они отображаются в виде файлов в утилите. Попробуйте следующее:

$ bash -c 'echo <(echo)'
/dev/fd/63
$ ksh -c 'echo <(echo)'
/dev/fd/4
$ zsh -c 'echo <(echo)'
/proc/self/fd/12

Вы увидите файловые дескрипторы, похожие на показанные.

Ответ 2

Это стандартное расширение Bash. <(sort file1) открывает трубку с выходом команды sort file1, передает трубку временное имя файла и передает это временное имя файла в командной строке comm.

Вы можете увидеть, как это работает, получив echo, чтобы сообщить вам, что передается программе:

echo <(sort file1) <(sort file2)