Глава 21. Подстановка процессов


Подстановка процессов — это аналог подстановки команд. Операция подстановки команд записывает в переменную результат выполнения некоторой команды, например, dir_contents=`ls -al` или xref=$(grep word datafile). Операция подстановки процессов передает вывод одного процесса на ввод другого (другими словами, передает результат выполнения одной команды — другой).

Шаблон подстановки команды

Внутри круглых скобок

>(command)

<(command)

Таким образом инициируется подстановка процессов. Здесь, для передачи результата работы процесса в круглых скобках, используются файлы /dev/fd/<n>. [50]

Note

Между круглой скобкой и символом "<" или ">", не должно быть пробелов, в противном случае это вызовет сообщение об ошибке.

  1. bash$ echo >(true)
  2. /dev/fd/63
  3. bash$ echo <(true)
  4. /dev/fd/63
  5.        
Bash создает канал с двумя файловыми дескрипторами, --fIn и fOut--. stdin команды true присоединяется к fOut (dup2(fOut, 0)), затем Bash передает /dev/fd/fIn в качестве аргумента команде echo. В системах, где отсутствуют файлы /dev/fd/<n>, Bash может использовать временные файлы. (Спасибо S.C.)

  1. cat <(ls -l)
  2. # То же самое, что и     ls -l | cat
  3. sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin)
  4. # Список файлов в трех основных каталогах 'bin', отсортированный по именам файлов.
  5. # Обратите внимание: на вход 'sort' поданы три самостоятельные команды.
  6. diff <(command1) <(command2)    # Выдаст различия в выводе команд.
  7. tar cf >(bzip2 -c > file.tar.bz2) $directory_name
  8. # Вызовет "tar cf /dev/fd/?? $directory_name" и затем "bzip2 -c > file.tar.bz2".
  9. #
  10. # Из-за особенностей, присущих некоторым системам, связанным с /dev/fd/<n>,
  11. # канал между командами не обязательно должен быть именованным.
  12. #
  13. # Это можно сделать и так.
  14. #
  15. bzip2 -c < pipe > file.tar.bz2&
  16. tar cf pipe $directory_name
  17. rm pipe
  18. #        или
  19. exec 3>&1
  20. tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
  21. exec 3>&-
  22. # Спасибо S.C.


Ниже приводится еще один очень интересный пример использования подстановки процессов.

  1. # Фрагмент сценария из дистрибутива SuSE:
  2. while read  des what mask iface; do
  3. # Некоторые команды ...
  4. done < <(route -n)
  5. # Чтобы проверить это, попробуем вставить команду, выполняющую какие либо действия.
  6. while read  des what mask iface; do
  7.   echo $des $what $mask $iface
  8. done < <(route -n)
  9. # Вывод на экран:
  10. # Kernel IP routing table
  11. # Destination Gateway Genmask Flags Metric Ref Use Iface
  12. # 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
  13. # Как указывает S.C. — более простой для понимания эквивалент:
  14. route -n |
  15.   while read des what mask iface; do   # Переменные берут значения с устройства вывода конвейера (канала).
  16.     echo $des $what $mask $iface
  17.   done  #  На экран выводится то же самое, что и выше.
  18.         #  Однако, Ulrich Gayer отметил, что ...
  19.         #+ этот вариант запускает цикл while в подоболочке,
  20.         #+ и поэтому переменные не видны за пределами цикла, после закрытия канала.

[50]    Имеет тот же эффект, что и именованные каналы (временный файл), фактически, именованные каналы некогда использовались в операциях подстановки процессов.