26.3.4. Игнорирование сигналов

26.3.4. Игнорирование сигналов

Когда пользователь регистрируется в системе, просматривается файл /etc/profile; нежелательно, чтобы пользователь прерывал этот процесс. Обычно задается перехват, или игнорирование, сигналов 1, 2, 3 и 15, но потом при просмотре сообщения motd (ежедневного сообщения) их подключают вновь (восстанавливают). Затем для игнорирования сигналов 1, 2, 3 и 15 снова устанавливается перехват.

Аналогичный подход можно, реализовать при работе со сценариями. Можно ввести понятие критического момента, который наступает при открытии большого количества файлов. Начиная с этого момента, нельзя прерывать выполнение сценария, поскольку это может повредить файлы. Для решения этой проблемы следует установить, команду trap, что позволит игнорировать некоторые сигналы. Когда завершится критический момент в функционировании сценария, примените команду trap, чтобы снова можно было захватывать сигналы.

Для игнорирования входящих сигналов (кроме сигнала 9) применяется следующая команда:

trap "" номер_сигнала:{n}

Обратите внимание, что двойные кавычки ничего не содержат. Чтобы восстановить перехват и заново захватывать сигналы, выполните команду:

trap "любые действия" номер_сигнала:{n}

Суммируем сведения о процессах игнорирования и выявления сигналов.

trap "" 1 2 3 15 # игнорирование сигналов code that does really critical stuff

trap "my_exit" 1 2 3 15 # выполните снова захват сигналов с помощью функции

# my_exit

Обратите внимание на сценарий, выполняющий критическую обработку. Цикл while аккуратно передвигает имеющийся критический момент. Для игнорирования сигналов 2, 3 и 15 применяется команда trap. После завершения цикла while, завершается еще один цикл while, но перехват уже восстановлен и прерывания разрешены.

Оба цикла while выполняются до завершения шести итераций, затем в цикле активизируется команда sleep. Благодаря этому имеется достаточно времени для того, чтобы прервать выполнение сценария.

Рассмотрим следующий сценарий:

$ pg trap_ignore

#!/bin/sh

#trap_ignore

#игнорирование сигналов

trap "" 1 2 3 15

LOOP=0

my_exit ()

# my_exit

{

echo "Received interrupt on count $LOOP"

echo "Now exiting…" exit 1

}

# критическая обработка, нельзя прерывать….

LOOP=0

while : do

LOOP=`expr $LOOP + 1`

echo "critical processing..$LOOP..you cannot interrupt me"

sleep 1

if [ "$LOOP" -eq 6 ]; then

break

fi

done

LOOP=0

#критическая обработка завершена, перехват задан снова, но разрешены прерывания

trap "my_exit" 1 2 3 15

while :

do

LOOP=`expr $LOOP + 1`

echo "Non?critical processing..$LOOP..interrupt me now if you want"

sleep 1

if [ "$LOOP" -eq 6 ]; then

break

fi

done

Если в процессе работы этого сценария попытаться нажать клавиши [Ctrl+C] во время выполнения первого цикла "критической обработки", ничего не произойдет. Это связано с тем, что была введена команда trap для игнорирования сигналов.

После того как начинается второй цикл "некритической обработки", статус команды trap восстанавливается, в результате чего разрешаются прерывания.

$ trap_ignore

critical processing..1..you cannot interrupt me

critical processing..2..you cannot interrupt me

critical processing..3..you cannot interrupt me

critical processing..4..you cannot interrupt me

critical processing..5..you cannot interrupt me

critical processing..6..you cannot interrupt me

Non?critical processing..1..interrupt me now if you want

Non?critical processing..2..interrupt me now if you want

Received interrupt on count 2

Now exiting…

Благодаря применению команды trap можно обрести большую степень контроля над "поведением" сценария при получении сигнала. Перехват и последующая обработка сигналов обеспечивают устойчивую работу сценариев.