Определение имени принятого сигнала в Bash - PullRequest
30 голосов
/ 13 февраля 2012

Когда сигнал получен, я могу выполнить некоторые команды, используя trap. Пример:

trap 'echo hello world' 1 2

Если какой-либо из указанных сигналов получен, отображается «Привет, мир».

Но как мне распечатать / идентифицировать имя принятого сигнала?

Ответы [ 4 ]

39 голосов
/ 13 февраля 2012

(Если у вас есть только номер сигнала и вы хотите его имя, kill -l $SIGNAL_NUM печатает имя сигнала; вы можете избежать этого, используя имена сигналов вместо номеров в вашем вызове на trap, как показано ниже. )

Этот ответ говорит, что единственный способ определить, какой сигнал вы перехватили в bash, - написать отдельную оболочку для каждого отдельного сигнала, который вы хотите перехватить. Еще один ответ на тот же вопрос предоставляет вам функцию-обертку:

Код:

#!/bin/bash

trap_with_arg() {
    func="$1" ; shift
    for sig ; do
        trap "$func $sig" "$sig"
    done
}

func_trap() {
    echo Trapped: $1
}

trap_with_arg func_trap INT TERM EXIT

read # Wait so the script doesn't exit.

Если я запускаю это, тогда я могу отправлять сигналы процессу, и я получаю вывод вроде

Trapped: INT
Trapped: TERM
Trapped: EXIT
8 голосов
/ 17 марта 2016

В ловушке (при срабатывании через сигнал) $? переменная изначально установлена ​​на номер сигнала плюс 128, так что вы можете присвоить номер сигнала переменной, сделав первый оператор действия прерывания что-то вроде

sig=$(($? - 128))

Затем вы можете получить название сигнала с помощью команды kill

kill -l $sig
3 голосов
/ 01 марта 2018

простой способ сделать это:

_handler() {
   signal=$1
   echo signal was $signal
 }

 trap '_handler SIGTERM' SIGTERM
 trap '_handler SIGINT'  SIGINT
1 голос
/ 19 сентября 2018

Ссылаясь на решение $?, приведенное выше: $? будет отражать код завершения последней выполненной команды.Учтите это:

#!/bin/bash
trap 'echo CODE: $?; exit 1' 1 2 3 15
sleep 3600

Если вы запустите это и нажмете Ctrl-C , будет напечатано CODE: 130.Это потому, что исполняемый файл sleep был прерван SIGINT и завершен с этим кодом.

Сравните это с:

#!/bin/bash
trap 'echo CODE: $?; exit 1' 1 2 3 15
read X

Если вы запустите это и нажмете Ctrl-C , он напечатает CODE: 0, предположительно потому, что команда read является встроенной, а правила кода выхода отличаются (то же самое происходит, если вы прервете while : ; do : ; done).

Итак, только $?сообщает вам о сигнале, если он прервал внешнюю команду, и , если эта конкретная программа не перехватила сигнал и вышла со своим собственным кодом выхода.В этом случае сценарий bash приведен выше: после получения SIGINT он завершится с кодом 1, а не 130.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...