Упражнение 5.12
Напишите версию команды watchwho
, в которой вывод команды who
хранится в переменных языка shell
, а не в файлах. Какая версия лучше? Какая версия быстрее работает? Следует ли в командах watchwho
и checkmail
автоматически использовать операцию &
?
Упражнение 5.13
В чем состоит различие между пустой командой языка shell
: и символом примечания #
? Нужны ли они?
5.4 Команда trap
: обработка прерываний
Если во время выполнения команды watchwho
нажать клавишу DEL ( УДЛ ) или отключить компьютер от сети, то один или несколько временных файлов останутся в каталоге /tmp
. Команда watchwho
удаляет временные файлы перед окончанием своей работы. Необходимы средства обнаружения таких ситуаций и восстановления после прерывания.
При нажатии клавиши DEL всем процессам, запущенным с этого терминала, посылается сигнал прерывания . Аналогично в случае отключения посылается сигнал отбоя. Существуют и другие сигналы. Если в программе не предусмотрены специальные действия по обработке сигналов, то указанные сигналы прекращают ее выполнение. Интерпретатор защищает программы, запущенные с помощью &
, от прерываний, но не от отключений.
В гл. 7 сигналы рассматриваются подробнее, но для работы с ними на языке shell
глубоких знаний не требуется. Встроенная команда интерпретатора trap
устанавливает последовательность команд, которая должна выполняться при возникновении сигнала:
trap последовательность_команд список_номеров_сигналов
Последовательность команд — единый аргумент, поэтому его почти всегда нужно брать в кавычки. Номера сигналов обозначаются небольшими целыми числами, например, 2 соответствует сигналу, возникающему при нажатии клавиши DEL , а 1 — сигналу, возникающему при отключении от сети. Номера сигналов, наиболее часто используемых в shell
-программах, приведены в табл. 5.4.
0 |
Выход из интерпретатора (по любой причине, включая конец файла) |
1 |
Отбой |
2 |
Прерывание (клавиша DEL ) |
3 |
Останов ( ctl-\ ; вызывает распечатку содержимого памяти программы) |
9 |
Уничтожение (нельзя перехватить или игнорировать) |
15 |
Окончание выполнения; сигнал по умолчанию, производимый kill(1) |
Таблица 5.4: Номера сигналов в интерпретаторе
Для удаления временных файлов в команде watchwho
вызов команды trap
должен указываться перед циклом, чтобы перехватить сигналы прерывания, отбоя и окончания выполнения:
...
trap 'rm -f $new $old; exit 1' 1 2 15
while:
...
Последовательность команд, образующих первый аргумент команды trap
, подобна вызову подпрограммы, который происходит сразу по возникновении сигнала. Когда эта последовательность окончится, прерванная программа возобновляется с места прерывания, если только сигнал не уничтожит ее. Таким образом, последовательность команд в trap
должна явно вызывать exit
, иначе shell
-программа продолжит свое выполнение после прерывания. Кроме того, последовательность команд будет читаться дважды: при установке команды trap
и при обращении к ней. Поэтому последовательность команд лучше защищать апострофами, чтобы значения переменных вычислялись только при выполнении программ, указанных в команде trap
. В данном случае это не имеет значения, но позднее вы столкнетесь с ситуацией, когда это важно. Кстати, флаг -f
предписывает команде rm
не задавать вопросов.
Иногда команду trap
полезно применять в диалоговом режиме, чаще всего для того, чтобы не допустить уничтожения программы сигналом отбоя, возникшим при обрыве телефонной связи:
$ (trap "" 1; долго_выполняемая команда) &
2134
$
Для процесса и его потомков пустая последовательность означает, что нужно игнорировать прерывания. При наличии скобок команда trap
и долго_выполняемая_команда
выполняются порожденным интерпретатором вместе и как фоновые; без них команда trap
действовала бы на исходный интерпретатор, так же как и на долго_выполняемую_команду.
Команда nohup(1)
— небольшая shell
-программа, обеспечивающая непрерывное выполнение команд. Ниже полностью приведен ее вариант из седьмой версии:
$ cat 'which nohup'
trap "" 1 15
if test -t 2>&1
Читать дальше
Конец ознакомительного отрывка
Купить книгу