Книга: Искусство программирования на языке сценариев командной оболочки
Пример 19-1. Область видимости переменных
Пример 19-1. Область видимости переменных
#!/bin/bash
# subshell.sh
echo
outer_variable=Outer
inner_variable=Inner
echo "Дочерний процесс, "inner_variable" = $inner_variable"
echo "Дочерний процесс, "outer" = $outer_variable"
echo
if [ -z "$inner_variable" ]
then
echo "Переменная inner_variable не определена в родительской оболочке"
else
echo "Переменная inner_variable определена в родительской оболочке"
fi
echo "Родительский процесс, "inner_variable" = $inner_variable"
# Переменная $inner_variable не будет определена
# потому, что переменные, определенные в дочернем процессе,
# ведут себя как "локальные переменные".
echo
exit 0
См. также Пример 31-1.
+
Смена текущего каталога в дочернем процессе (подоболочке) не влечет за собой смену текущего каталога в родительской оболочке.
Пример 19-2. Личные настройки пользователей
#!/bin/bash
# allprofs.sh: вывод личных настроек (profiles) всех пользователей
# Автор: Heiner Steven
# С некоторыми изменениями, внесенными автором документа.
FILE=.bashrc # Файл настроек пользователя,
#+ в оригинальном сценарии называется ".profile".
for home in `awk -F: '{print $6}' /etc/passwd`
do
[ -d "$home" ] || continue # Перейти к следующей итерации, если нет домашнего каталога.
[ -r "$home" ] || continue # Перейти к следующей итерации, если не доступен для чтения.
(cd $home; [ -e $FILE ] && less $FILE)
done
# По завершении сценария -- нет теобходимости выполнять команду 'cd', чтобы вернуться в первоначальный каталог,
#+ поскольку 'cd $home' выполняется в подоболочке.
exit 0
Подоболочка может использоваться для задания "специфического окружения" для группы команд.
COMMAND1
COMMAND2
COMMAND3
IFS=:
PATH=/bin
unset TERMINFO
set -C
shift 5
COMMAND4
COMMAND5
exit 3 # Выход только из подоболочки.
# Изменение переменных окружения не коснется родительской оболочки.
COMMAND6
COMMAND7
Как вариант использования подоболочки -- проверка переменных.
if (set -u; : $variable) 2> /dev/null
then
echo "Переменная определена."
fi
# Можно сделать то же самое по другому: [[ ${variable-x} != x || ${variable-y} != y ]]
# или [[ ${variable-x} != x$variable ]]
# или [[ ${variable+x} = x ]])
Еще одно применение -- проверка файлов блокировки:
if (set -C; : > lock_file) 2> /dev/null
then
echo "Этот сценарий уже запущен другим пользователем."
exit 65
fi
# Спасибо S.C.
Процессы в подоболочках могут исполняться параллельно. Это позволяет разбить сложную задачу на несколько простых подзадач, выполняющих параллельную обработку информации.
Пример 19-3. Запуск нескольких процессов в подоболочках
(cat list1 list2 list3 | sort | uniq > list123) &
(cat list4 list5 list6 | sort | uniq > list456) &
# Слияние и сортировка двух списков производится одновременно.
# Запуск в фоне гарантирует параллельное исполнение.
#
# Тот же эффект дает
# cat list1 list2 list3 | sort | uniq > list123 &
# cat list4 list5 list6 | sort | uniq > list456 &
wait # Ожидание завершения работы подоболочек.
diff list123 list456
Перенаправление ввода/вывода в/из подоболочки производится оператором построения конвейера "|", например, ls -al | (command).
{ command1; command2; command3; ... }