Завершение работы процесса с клавиатуры
Временная остановка процесса
Комбинация клавиш CTRL + Z позволяет сгенерировать сигнал SIGTSTP, который приостанавливает работу процесса, но не завершает его выполнение. Такой процесс остаётся в памяти, его работу можно возобновить.
Выполним в оболочке команду:
$ sleep 100
И временно остановим её комбинацией клавиш CTRL + Z.
Приостановка процесса
Число в квадратных скобках — это номер задания, который оболочка назначает процессу. Оболочка рассматривает процессы, выполняющиеся в ней, как задания с уникальными номерами. Первому процессу назначается номер 1, второму — 2, и так далее.
Если вы приостановите задание, привязанное к оболочке, и попытаетесь выйти из неё, bash выдаст предупреждение.
Просмотреть приостановленные задания можно такой командой:
ps –l
Список заданий
В колонке S, выводящей состояние процесса, для приостановленных процессов выводится T. Это указывает на то, что команда либо приостановлена, либо находится в состоянии трассировки.
Если нужно завершить работу приостановленного процесса, можно воспользоваться командой kill. Подробности о ней можно почитать здесь. Выглядит её вызов так:
kill processID
Перехват сигналов
Для того, чтобы включить в скрипте отслеживание сигналов Linux, используется команда trap. Если скрипт получает сигнал, указанный при вызове этой команды, он обрабатывает его самостоятельно, при этом оболочка такой сигнал обрабатывать не будет.
Команда trap позволяет скрипту реагировать на сигналы, в противном случае их обработка выполняется оболочкой без его участия.
Рассмотрим пример, в котором показано, как при вызове команды trap задаётся код, который надо выполнить, и список сигналов, разделённых пробелами, которые мы хотим перехватить. В данном случае это всего один сигнал:
#!/bin/bash
trap "echo ' Trapped Ctrl-C'" SIGINT
echo This is a test script
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
Команда trap, использованная в этом примере, выводит текстовое сообщение всякий раз, когда она обнаруживает сигнал SIGINT, который можно сгенерировать, нажав Ctrl + C на клавиатуре.
Перехват сигналов
Каждый раз, когда вы нажимаете клавиши CTRL + C, скрипт выполняет команду echo, указанную при вызове trace вместо того, чтобы позволить оболочке завершит его работу.
Перехват сигнала выхода из скрипта
Перехватить сигнал выхода из скрипта можно, использовав при вызове команды trap имя сигнала EXIT:
#!/bin/bash
trap "echo Goodbye..." EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
Перехват сигнала выхода из скрипта
При выходе из скрипта, будь то нормальное завершение его работы или завершение, вызванное сигналом SIGINT, сработает перехват и оболочка исполнит команду echo.
Модификация перехваченных сигналов и отмена перехвата
Для модификации перехваченных скриптом сигналов можно выполнить команду trap с новыми параметрами:
#!/bin/bash
trap "echo 'Ctrl-C is trapped.'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
trap "echo ' I modified the trap!'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Second Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
Модификация перехвата сигналов
После модификации сигналы будут обрабатываться по-новому.
Перехват сигналов можно и отменить, для этого достаточно выполнить команду trap, передав ей двойное тире и имя сигнала:
#!/bin/bash
trap "echo 'Ctrl-C is trapped.'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
trap -- SIGINT
echo "I just removed the trap"
count=1
while [ $count -le 5 ]
do
echo "Second Loop #$count"
sleep 1
count=$(( $count + 1 ))
done
Если скрипт получит сигнал до отмены перехвата, он обработает его так, как задано в действующей команде trap.
Запустим скрипт:
$ ./myscript
И нажмём CTRL + C на клавиатуре.
Сигнал, перехваченный до отмены перехвата
Первое нажатие CTRL + C пришлось на момент исполнения скрипта, когда перехват сигнала был в силе, поэтому скрипт исполнил назначенную сигналу команду echo. После того, как исполнение дошло до команды отмены перехвата, команда CTRL + C сработала обычным образом, завершив работу скрипта.