Получить имена сигналов из чисел в Python - PullRequest
46 голосов
/ 31 марта 2010

Есть ли способ сопоставить номер сигнала (например, signal.SIGINT) с его соответствующим именем (то есть "SIGINT")?

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

import signal
def signal_handler(signum, frame):
    logging.debug("Received signal (%s)" % sig_names[signum])

signal.signal(signal.SIGINT, signal_handler)

Для некоторых словарей sig_names, поэтому, когда процесс получает SIGINT, он печатает:

Received signal (SIGINT)

Ответы [ 7 ]

56 голосов
/ 14 марта 2016

С добавлением signal.Signals enum в Python 3.5 теперь это так же просто, как:

>>> import signal
>>> signal.SIGINT.name
'SIGINT'
>>> signal.SIGINT.value
2
>>> signal.Signals(2).name
'SIGINT'
>>> signal.Signals['SIGINT'].value
2
32 голосов
/ 31 марта 2010

Нет, но если вы не возражаете против небольшого взлома, вы можете сгенерировать его так:

import signal
dict((k, v) for v, k in reversed(sorted(signal.__dict__.items()))
     if v.startswith('SIG') and not v.startswith('SIG_'))
12 голосов
/ 16 декабря 2011

Стандартная библиотека Python By Example показывает эту функцию в главе о сигналах:

SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \
    for n in dir(signal) if n.startswith('SIG') and '_' not in n )

Затем вы можете использовать его так:

print "Terminated by signal %s" % SIGNALS_TO_NAMES_DICT[signal_number]
3 голосов
/ 08 апреля 2011

Я нашел эту статью, когда находился в той же ситуации, и подумал, что обработчик обрабатывает только один сигнал за раз, поэтому мне даже не нужен целый словарь, только имя одного сигнала:

sig_name = tuple((v) for v, k in signal.__dict__.iteritems() if k == signum)[0]

вероятно, существует нотация, которая не нуждается в кортеже (...) [0], но я не могу понять это.

1 голос
/ 31 марта 2010

Ну, help(signal) говорит внизу:

DATA
    NSIG = 23
    SIGABRT = 22
    SIGBREAK = 21
    SIGFPE = 8
    SIGILL = 4
    SIGINT = 2
    SIGSEGV = 11
    SIGTERM = 15
    SIG_DFL = 0
    SIG_IGN = 1

Так что это должно работать:

sig_names = {23:"NSIG", 22:"SIGABRT", 21:"SIGBREAK", 8:"SIGFPE", 4:"SIGILL",
             2:"SIGINT", 11:"SIGSEGV", 15:"SIGTERM", 0:"SIG_DFL", 1:"SIG_IGN"}
0 голосов
/ 03 июля 2018

для signal_value положительного числа (номер сигнала) или отрицательного значения (состояние возврата из подпроцесса):

import signal

signal_name = {
        getattr(signal, _signame): _signame
        for _signame in dir(signal)
        if _signame.startswith('SIG')
    }.get(abs(signal_value), 'Unknown')
0 голосов
/ 09 апреля 2016

Опираясь на другой ответ :

import signal

if hasattr(signal, "Signals"):
    def _signal_name(signum):
        try:
            return signal.Signals(signum).name
        except ValueError:
            pass
else:
    def _signal_name(signum):
        for n, v in sorted(signal.__dict__.items()):
            if v != signum:
                continue
            if n.startswith("SIG") and not n.startswith("SIG_"):
                return n

def signal_name(signum):
    if signal.SIGRTMIN <= signum <= signal.SIGRTMAX:
        return "SIGRTMIN+{}".format(signum - signal.SIGRTMIN)
    x = _signal_name(signum)
    if x is None:
        # raise ValueError for invalid signals
        signal.getsignal(signum)
        x = "<signal {}>".format(signum)
    return x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...