MyTetra Share
Делитесь знаниями!
trap / перехват команд выхода из приложения / скрипта
Время создания: 31.08.2017 20:51
Текстовые метки: code
Раздел: bash - команды
Запись: xintrea/mytetra_db_mcold/master/base/1501681068i79wd7bu3x/text.html на raw.githubusercontent.com

BASH: использование команды trap для перехвата сигналов прерывания процесса

By мережевий хробачок™ | 11/20/2013

0 Comments


  • Rate this (2 Votes)

Про команду kill и сигналы управления процессами (SIGKILLSIGTERM и другие) можно прочитать в статье Linux&FreeBSD: команды kill, nohup — сигналы и управление процессами.

У bash имеется встроенная команда trap, которая может перехватывать такие команды и выполнять какие-либо действия, заданные ей.

Синтаксис команды:

trap command signals

command – что именно необходимо выполнить при перехвате сигнала;
signals – список сигналов, которые необходимо перехватывать. Сигналы можно указывать как в полном виде – SIGTERM, так и в виде кода – 1, 2 и т.д.

Рассмотрим простой пример скрипта, в котором цикл будет выполняться до тех пор, пока не получит сигнал Ctrl+C (SIGINT – interrupt) или не достигнет значения 100 для переменной $count:


01

cat trap-1.sh


02

#!/bin/bash


03

count=0


04

 


05

trap 'echo "Exit"; exit 1' 2


06

 


07

while [ $count -lt 100 ]


08

do


09

sleep 1


10

(( count++ ))


11

echo $count


12

done

Про циклы читайте в статье BASH: описание циклов for, while, until и примеры использования.

Пример его выполнения:


1

$ ./trap-1.sh


2

1


3

2


4

3


5

Exit

После получения сигнала SIGINT (Ctrl+Ctrap выполнил команду 'echo "Exit"'и сразу за ней – "exit 1", завершив работу скрипта. В этом примере сигнал, который надо перехватить задан в виде кода – SIGINT = 2 и т.д.

Список кодов наиболее используемых сигналов в таблице ниже:

SIGNAL NAME

SIGNAL NUMBER

DESCRIPTION

SIGHUP

1

Hang up detected on controlling terminal or death of controlling process

SIGINT

2

Issued if the user sends an interrupt signal (Ctrl + C).

SIGQUIT

3

Issued if the user sends a quit signal (Ctrl + D).

SIGFPE

8

Issued if an illegal mathematical operation is attempted

SIGKILL

9

If a process gets this signal it must quit immediately and will not perform any clean-up operations

SIGALRM

14

Alarm Clock signal (used for timers)

SIGTERM

15

Software termination signal (sent by kill by default).

Команде trap можно передавать список сигналов, разделённые пробелами:


1

trap 'echo "Exit"; exit 1' 1 2 3 15

В качестве команды trap может принимать функции. Возьмём пример функции answer и немного переделаем наш скрипт:


01

cat trap.sh


02

#!/bin/bash


03

count=0


04

 


05

answer () {


06

while read response; do


07

echo


08

case $response in


09

[yY][eE][sS]|[yY])


10

printf "$1n"


11

return 0


12

#$2


13

break


14

;;


15

[nN][oO]|[nN])


16

printf "$2n"


17

return 1


18

#$4


19

break


20

;;


21

*)


22

printf "Please, enter Y(yes) or N(no)! "


23

esac


24

done


25

}


26

 


27

trap 'printf "Are you sure to skip? [Y/n] "; answer && printf "nSkipping...nn" && exit 1 ' SIGINT


28

 


29

while [ $count -lt 100 ]


30

do


31

sleep 1


32

(( count++ ))


33

echo $count


34

done

Тут мы задали сигнал в виде имени – SIGINT. Посмотрим, как выполняется такой скрипт:


01

$ ./trap.sh


02

1


03

2


04

 


05

3


06

Are you sure to skip? [Y/n] n


07

 


08

4


09

5


10

 


11

6


12

Are you sure to skip? [Y/n] y


13

 


14

Skipping...

Таким же образом можно заставить скрипт игнорировать полученные сигналы (кроме kill -9 - "SIGKILL", который уничтожит процесс в любом случае). Для это вместо команды – просто укажите пустые одинарные кавычки – ''. Пример:


01

cat trap-2.sh


02

#!/bin/bash


03

count=0


04

 


05

trap '' 2


06

 


07

while [ $count -lt 100 ]


08

do


09

sleep 1


10

(( count++ ))


11

echo $count


12

done


1

$ ./trap-2.sh


2

1


3

2


4

3


5

...


6

18


7

19


8

20


9

Terminated

Процесс нельзя будет прервать комбинацией Ctrl+C, но он был прерван командой kill (SIGTERM, код 15 используется kill по-умолчанию).

Если же добавить код 15:

view source


1

trap '' 2 15

То прервать выполнение можно будет только с помощью kill -9.

 
MyTetra Share v.0.59
Яндекс индекс цитирования