Если ограничиться написанием сценариев, следует обращать внимание только на сигналы 1,2,3 и 15. Если сценарий получает сигнал, возможен один из трех вариантов дальнейших действий: 1. Ничего не предпринимать, система самостоятельно отреагирует на полученный
сигнал.
1. Захватить сигнал, но игнорировать его.
2. Захватить сигнал и предпринять определенные действия.
Большинство сценариев используют сигнал с номером 1. Этот метод применяется далее в книге во всех сценариях.
Чтобы применить два других метода, нужно воспользоваться командой trap.
26.3. Команда trap
Команда trap позволяет перехватывать сигналы. Формат команды trap:
trap "имя" сигнал(ы)
Имя представляет собой функцию, содержащую инструкции, которые выполняются при перехвате сигнала. В действительности функцию следует называть так, чтобы ее имя было связано именно с перехваченными сигналами. Имя следует заключать в двойные кавычки (""). Сигналы являются входящими.
Когда сигнал перехватывается, сценарий обычно находится в стадии обработки. Самые распространенные действия следующие:
1. Очистить временные файлы.
2. Игнорировать сигналы.
3. Запросить пользователя, следует ли завершить сценарий.
Ниже приводится таблица, где описаны наиболее распространенные варианты применения команды trap:
trap "" 2 3
Игнорирование сигналов 2 и 3; пользователь не может
завершить сценарий
trap "команды" 2 3
Если захвачены сигналы 2 и 3, выполняются команды
trap 2 3
Восстановление сигналов 2 и 3; пользователь может завер-
шить сценарий
Вместо двойных кавычек можно использовать одинарные; результат будет аналогичен.
А теперь создадим сценарий, выполняющий подсчет итераций до тех пор, пока пользователь не нажмет комбинацию клавиш [Ctrl+C] (сигнал 2). После этого сценарий отобразит сообщение, содержащее номер текущей итерации цикла.
В этом случае применяется следующий формат:
trap "какие‑либо действия" номер сигнала: (s)
Соответствующий сценарий имеет вид:
$ pg trap1
#!/bin/sh
#trap1
trap "my_exit" 2
LOOP=0
my_exit ()
{
echo "You just hit
echo " I will now exit "
exit 1
}
while : do
LOOP=`expr $LOOP + 1`
echo $LOOP
done
Рассмотрим сценарий более подробно.
trap "my_exit" 2
В результате выполнения команды trap после получения сигнала 2 выполняется команда, заключенная в двойные кавычки; в данном случае вызывается функция
my_exit.
my_exit ()
{
echo "You just hit
echo " I will now exit "
exit 1
}
Функция myexit вызывается при получении сигнала 2; при этом отображается значение переменной $LOOP, информирующее пользователя о том, какая итерация цикла выполнялась при нажатии комбинации клавиш [Ctrl+C]. Функции подобного типа применяются на практике для удаления временных файлов.
При выполнении сценария получим следующие результаты:
$ trap1
211 212
You just hit
Наиболее часто выполняемым действием является удаление временных файлов.
В следующем сценарии с помощью команд df и ps непрерывно добавляется информация во временные файлы HOLD1.$$ и HOLD2.$$. Не забывайте, что символы $$ заменяют ID процесса. Когда пользователь нажимает комбинацию клавиш [Ctrl+C], эти файлы удаляются.
$ pg trap2
#!/bin/sh
# trap2
# перехват только сигнала 2….
trap "my_exit" 2
HOLD1=/tmp/HOLD1.$$
HOLD2=/tmp/HOLD2.$$
my_exit {)
{
# my_exit
echo "
# удаление временных файлов
rm /tmp/*.$$ 2>/dev/null
exit 1
}
echo "processing…."
# основной цикл
while :
do
df >> $HOLD1
ps xa >>$HOLD2
done
Результаты выполнении этого сценария будут следующими:
$ trap2
processing….
При получении сигнала можно предоставлять пользователю определенный выбор. Однако если получены сигналы 2 или 3, следует убедиться, что они не появились случайно. Необходимо предусмотреть поток ошибок, благодаря чему выявляется ошибочное нажатие клавиш [Ctrl+C].
В следующем примере пользователю предоставляется возможность решить, следует ли выйти из сценария после получения сигнала 2. Отображается запрос о том, действительно ли пользователь желает завершить работу. Для уточнения предпринимаемого действия применяется конструкция case.