Главная » Программирование для UNIX » Команда trap: перехват прерываний

0

Если  нажать клавишу Del или  повесить телефонную трубку во время выполнения команды watchwho, в каталоге /tmp останутся один или  два временных файла. Перед  выходом watchwho должна удалять свои  временные файлы. Необходимо иметь возможность обнаруживать подобные ситуации и способ восстановления нормального хода событий.

При  нажатии клавиши Del сигнал прерывания посылается всем  процессам, работающим на терминале в настоящий момент. Аналогично, когда повешена телефонная трубка,  отправляется сигнал отбоя.  Существуют и другие сигналы. До тех пор пока  программа не обрабатывает  сигналы явно, сигнал будет завершать ее выполнение. Оболочка защищает  программы, запущенные с использованием &  от  прерываний, но не от отсоединения.

В главе 7 будет подробно рассказано о сигналах, а для того чтобы обрабатывать их в оболочке, надо знать лишь немногое. Встроенная в оболочку команда trap  определяет  последовательность команд, которая должна быть выполнена, когда поступит сигнал:

trap последовательность5команд список5номеров5сигналов

Последовательность5команд является  единым  аргументом, так  что почти всегда  приходится заключать ее в кавычки. Номера сигналов – это целые числа, идентифицирующие сигналы. Например, 2 – это сигнал, генерируемый при нажатии клавиши Del, а 1 – сигнал, генерируемый, когда повешена телефонная трубка. Номера сигналов, наиболее часто  используемых при  программировании в оболочке, перечислены в табл. 5.4.

Таблица 5.4. Номера сигналов оболочки

Номер

Значение

0

1

2

3

9

15

выход из оболочки (по любой причине, в том числе в конце файла) отбой (повешена телефонная трубка)

прерывание (клавиша Dela)

выход (ctl-\; требует от программы создания дампа памяти) kill (не может быть ни перехвачен, ни проигнорирован) завершение – сигнал, по умолчанию генерируемый kill(1)

a        На клавиатурах старых терминалов была специальная клавиша Del, выда вавшая сигнал прерывания. Для  того чтобы послать текущему процессу SIGINT, используйте комбинацию клавиш Ctrl+C. – Примеч. науч. ред.

Поэтому для того, чтобы  очистить временные файлы в watchwho, непосредственно перед циклом следует поместить команду trap для пере хвата сигналов отбоя, прерывания и завершения:

trap ‘rm  –f  $new $old;  exit 1′ 1 2  15 while  :

Последовательность команд, образующая  первый аргумент trap,  подобна обращению к подпрограмме, которое происходит сразу  же после  получения сигнала. Когда  она заканчивается, программа, которая выполнялась, будет возобновлена с того места, в котором она находилась до  получения  сигнала.  Таким  образом, последовательность команд trap должна явно запустить exit, иначе программа оболочки будет продолжать выполняться после прерывания. Еще одно замечание – после довательность команд будет  прочитана дважды: в момент установки trap и в момент обращения к ней.  Поэтому лучше поместить последовательность команд в  одинарные кавычки,  тогда  переменные будут вычисляться только при  выполнении функций  trap. В примере, рассматриваемом сейчас, это не имеет  особого  значения, но позже будет приведен еще один пример, для  которого это важно. Параметр –f ука зывает команде rm, что она не должна задавать вопросов.

Бывает, что trap оказывается удобной  при интерактивной работе, чаще всего это происходит тогда, когда надо предотвратить уничтожение программы сигналом отбоя,  сгенерированным прерванным телефонным соединением:

$ (trap  ” 1;  долго-выполняющаяся-команда)  &

2134

$

Пустая  последовательность команд означает  требование «игнорировать  прерывания» в данном процессе и в порожденных им процессах. Скобки в записи команды являются причиной того, что trap и команда выполняются вместе  в фоновом режиме в подоболочке; если бы скобок не было, то trap была  бы применена и к родительской оболочке и к дол– го–выполняющейся–команде.

Команда nohup(1)  – это коротенькая программа оболочки, предоставляющая такую услугу. Вот ее полная версия в седьмой версии:

$ cat  `which  nohup`

trap ""  1 15

if test  –t  2>&1 then

else fi

$

echo  "Sending  output   to  ‘nohup.out’" exec  nice  –5  $*  >>nohup.out  2>&1

exec  nice  –5 $* 2>&1

Команда test  –t проверяет, является ли стандартный вывод  терминалом,  для того чтобы знать, надо ли сохранять выходные данные. Про-

грамма запускается в фоновом режиме с nice, получая таким образом более  низкий  приоритет,  чем  интерактивные программы.  (Обратите внимание на то, что nohup не задает PATH. Должна ли она это делать?)

Команда exec включена только для  повышения  производительности; без нее  команды выполнялись бы точно  так  же, как и с ней.  Но exec встроена в оболочку, она  заменяет процесс выполняющейся в данное время оболочки указанной программой, экономя таким образом один  процесс – оболочку, которая обычно ожидала бы завершения программы.  Можно было  использовать команду exec и во многих других местах, например в конце улучшенной программы cal, когда происходит обращение к /usr/bin/cal.

Кстати, сигнал 9 – это тот сигнал, который не может быть перехвачен или проигнорирован; он уничтожает всегда. Из оболочки он посылается следующим образом:

$ kill -9  идентификатор5процесса  

По умолчанию  kill –9 не используется, потому что у процесса, унич тожаемого таким сигналом, нет  возможности «привести дела  в порядок», прежде чем умереть.

Упражнение 5.14.   Версия программы nohup,  представленная выше, объединяет стандартный вывод  ошибок со стандартным выходным потоком. Хорошо ли это? Если нет,  то как аккуратно отделить их друг от друга?

Упражнение 5.15.  Найдите встроенную в оболочку команду times и добавьте  в свой .profile  строку так, чтобы  при  выходе из системы оболочка сообщала, сколько было использовано процессорного времени.

Упражнение 5.16.  Напишите программу, которая искала бы следую щий  доступный идентификатор пользователя в /etc/passwd. Если вам это интересно (и есть соответствующие права), переделайте таким образом команду, добавляющую нового пользователя в систему. Какие нужны права? Как следует обрабатывать прерывания?

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии