Get signal names from numbers in Python

PythonSignals

Python Problem Overview


Is there a way to map a signal number (e.g. signal.SIGINT) to its respective name (i.e. "SIGINT")?

I'd like to be able to print the name of a signal in the log when I receive it, however I cannot find a map from signal numbers to names in Python, i.e.:

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

signal.signal(signal.SIGINT, signal_handler)

For some dictionary sig_names, so when the process receives SIGINT it prints:

Received signal (SIGINT)

Python Solutions


Solution 1 - Python

With the addition of the signal.Signals enum in Python 3.5 this is now as easy as:

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

Solution 2 - Python

There is none, but if you don't mind a little hack, you can generate it like this:

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

Solution 3 - Python

The Python Standard Library By Example shows this function in the chapter on signals:

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

You can then use it like this:

print "Terminated by signal %s" % SIGNALS_TO_NAMES_DICT[signal_number]

Solution 4 - Python

As of Python 3.8, you can now use the signal.strsignal() method to return a textual description of the signal:

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

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

Solution 5 - Python

I found this article when I was in the same situation and figured the handler is only handling one signal at a time, so I don't even need a whole dictionary, just the name of one signal:

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

there's probably a notation that doesn't need the tuple(...)[0] bit, but I can't seem to figure it out.

Solution 6 - Python

Well, help(signal) says at the bottom:

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

So this should work:

sig_names = {23:"NSIG", 22:"SIGABRT", 21:"SIGBREAK", 8:"SIGFPE", 4:"SIGILL",
             2:"SIGINT", 11:"SIGSEGV", 15:"SIGTERM", 0:"SIG_DFL", 1:"SIG_IGN"}

Solution 7 - Python

Building on 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

Solution 8 - Python

for signal_value of positive number (signal number), or negative value (return status from subprocess):

import signal

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrian M. HuntView Question on Stackoverflow
Solution 1 - PythonpR0PsView Answer on Stackoverflow
Solution 2 - PythonWolphView Answer on Stackoverflow
Solution 3 - Pythondevin_sView Answer on Stackoverflow
Solution 4 - PythonPiranhaPhishView Answer on Stackoverflow
Solution 5 - PythonsscView Answer on Stackoverflow
Solution 6 - PythonDaniel GView Answer on Stackoverflow
Solution 7 - PythonRoger PateView Answer on Stackoverflow
Solution 8 - Pythonuser6331769View Answer on Stackoverflow