从Python中的数字中获取信号名称

时间:2010-03-31 01:51:48

标签: python signals

有没有办法将信号编号(例如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)

8 个答案:

答案 0 :(得分:54)

在Python 3.5中添加signal.Signals enum后,现在就像这样简单:

>>> import signal
>>> signal.SIGINT.name
'SIGINT'
>>> signal.SIGINT.value
2
>>> signal.Signals(2).name
'SIGINT'
>>> signal.Signals['SIGINT'].value
2

答案 1 :(得分:31)

没有,但如果你不介意一点点黑客攻击,你可以像这样生成它:

import signal
dict((k, v) for v, k in reversed(sorted(signal.__dict__.items()))
     if v.startswith('SIG') and not v.startswith('SIG_'))

答案 2 :(得分:12)

Python标准库按示例在有关信号的章节中显示了此功能:

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 :(得分:3)

当我处于相同的情况时发现这篇文章并且认为处理程序一次只处理一个信号,所以我甚至不需要一个完整的字典,只需要一个信号的名称:

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

可能有一个不需要元组(...)[0]位的符号,但我似乎无法弄明白。

答案 4 :(得分:2)

从Python 3.8开始,您现在可以使用signal.strsignal()方法来返回信号的文本描述:

>>> signal.strsignal(signal.SIGTERM)
'Terminated'

>>> signal.strsignal(signal.SIGKILL)
'Killed'

答案 5 :(得分:1)

嗯,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"}

答案 6 :(得分:0)

another answer

为基础
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

答案 7 :(得分:0)

对于signal_value为正数(信号号)或负数(子过程的返回状态):

import signal

signal_name = {
        getattr(signal, _signame): _signame
        for _signame in dir(signal)
        if _signame.startswith('SIG')
    }.get(abs(signal_value), 'Unknown')