Get signal names from numbers in Python
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)
Solution 1:
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:
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:
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:
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:
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.