Книга: Искусство программирования на языке сценариев командной оболочки

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

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

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

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

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

>(command)

<(command)

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


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

bash$ echo >(true)

/dev/fd/63

bash$ echo <(true)

/dev/fd/63

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

cat <(ls -l)

# То же самое, что и ls -l | cat

sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin)

# Список файлов в трех основных каталогах 'bin', отсортированный по именам файлов.

# Обратите внимание: на вход 'sort' поданы три самостоятельные команды.

diff <(command1) <(command2) # Выдаст различия в выводе команд.

tar cf >(bzip2 -c > file.tar.bz2) $directory_name

# Вызовет "tar cf /dev/fd/?? $directory_name" и затем "bzip2 -c > file.tar.bz2".

#

# Из-за особенностей, присущих некоторым системам, связанным с /dev/fd/<n>,

# канал между командами не обязательно должен быть именованным.

#

# Это можно сделать и так.

#

bzip2 -c < pipe > file.tar.bz2&

tar cf pipe $directory_name

rm pipe

# или

exec 3>&1

tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-

exec 3>&-

# Спасибо S.C.

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

# Фрагмент сценария из дистрибутива SuSE:

while read des what mask iface; do

# Некоторые команды ...

done < <(route -n)

# Чтобы проверить это, попробуем вставить команду, выполняющую какие либо действия.

while read des what mask iface; do

echo $des $what $mask $iface

done < <(route -n)

# Вывод на экран:

# Kernel IP routing table

# Destination Gateway Genmask Flags Metric Ref Use Iface

# 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo

# Как указывает S.C. -- более простой для понимания эквивалент:

route -n |

while read des what mask iface; do # Переменные берут значения с устройства вывода конвейера (канала).

echo $des $what $mask $iface

done # На экран выводится то же самое, что и выше.

# Однако, Ulrich Gayer отметил, что ...

#+ этот вариант запускает цикл while в подоболочке,

#+ и поэтому переменные не видны за пределами цикла, после закрытия канала.

Оглавление книги


Генерация: 1.676. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз