Напоминаем, что обычно сценарии обрабатываются интерпретатором сверху вниз, поэтому вы должны задать, команду
trap
перед той частью сценария, которую хотите защитить.
Для возврата к стандартной реакции на сигнал, просто задайте
команду
как -
. Для игнорирования сигнала задайте в
команде
пустую строку
''
. Команда trap без параметров выводит текущий список перехватов и действий.
В табл. 2.9 перечислены самые важные, включенные в. стандарт Х/Open сигналы, которые можно отследить (со стандартными номерами в скобках). Дополнительную информацию можно найти на страницах раздела 7 интерактивного справочного руководства, посвященного сигналам (
man 7 signal
).
Таблица 2.9
Сигнал | Описание |
HUP (1)
| Неожиданный останов; обычно посылается, когда отключается терминал или пользователь выходит из системы |
INT (2)
| Прерывание; обычно посылается нажатием комбинации клавиш <Ctrl>+<C> |
QUIT (3)
| Завершение выполнения; обычно посылается нажатием комбинации клавиш <Ctrl>+<\> |
ABRT (6)
| Аварийное завершение; обычно посылается при возникновении серьезной ошибки выполнения |
ALRM (14)
| Аварийный сигнал; обычно посылается для обработки превышений лимита времени |
TERM (15)
| Завершение; обычно посылается системой, когда она завершает работу |
А теперь выполните упражнение 2.15.
Упражнение 2.15. Сигналы прерываний
В следующем сценарии показана простая обработка сигнала.
#!/bin/sh
trap 'rm -f /tmp/my_tmp_file_$$' INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt..."
while [ -f /tmp/my_tmp_file_$$ ] ; do
echo File exists
sleep 1
done
echo The file no longer exists trap INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt..."
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo we never get here
exit 0
Если вы выполните этот сценарий, нажимая и удерживая нажатой клавишу <Ctrl> и затем нажимая клавишу <C> (или любую другую прерывающую комбинацию клавиш) в каждом из циклов, то получите следующий вывод:
creating file /tmp/my_tmp_file_141
press interrupt (CTRL-C) to interrupt ...
File exists
File exists
File exists
File exists
The file no longer exists
creating file /tmp/my tmp_file_141
press interrupt (CTRL-C) to interrupt ...
File exists
File exists
File exists
File exists
Как это работает
Сценарий использует команду
trap
для организации выполнения команды
rm -f /tmp/my_tmp_file_$$
при возникновении сигнала
INT
(прерывание). Затем сценарий выполняет цикл
while
до тех пор, пока существует файл. Когда пользователь нажимает комбинацию клавиш <Ctrl>+<C>, выполняется команда
rm -f /tmp/my_tmp_file_$$
, а затем возобновляется выполнение цикла
while
. Поскольку теперь файл удален, первый цикл
while
завершается стандартным образом.
Далее сценарий снова применяет команду
trap
, на этот раз для того, чтобы сообщить, что при возникновении сигнала
INT
никакая команда не выполняется. Затем сценарий создает заново файл и выполняет второй цикл
while
. Когда пользователь снова нажимает комбинацию клавиш <Ctrl>+<C>, не задана команда для выполнения, поэтому реализуется стандартное поведение: немедленное прекращение выполнения сценария. Поскольку сценарий завершается немедленно, заключительные команды
echo
и
exit
никогда не выполняются.
unset
Команда
unset
удаляет переменные или функции из окружения. Она не может проделать это с переменными, предназначенными только для чтения и определенными командной оболочкой, такими как
IFS
. Команда применяется редко.
В следующем сценарии сначала выводится строка
Hello world
, а во второй раз новая строка.
#!/bin/sh
foo="Hello World"
echo $foo
unset foo
echo $foo
Примечание
Написание
foo=
подобно, но не идентично применению команды
unset
в только что приведенной программе. Оператор
foo=
задает для переменной
foo
значение
null
, но при этом переменная
foo
все еще существует. Команда
unset foo
удаляет из окружения переменную
foo
.