Python - Trap all signals

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

In python 2.6 under Linux, I can use the following to handle a TERM signal:

import signal def handleSigTERM():     shutdown() signal.signal(signal.SIGTERM, handleSigTERM)     

Is there any way to setup a handler for all signals received by the process, other than just setting them up one-at-a-time?

回答1:

You could just loop through the signals in the signal module and set them up.

for i in [x for x in dir(signal) if x.startswith("SIG")]:   try:     signum = getattr(signal,i)     signal.signal(signum,sighandler)   except (OSError, RuntimeError) as m: #OSError for Python3, RuntimeError for 2     print ("Skipping {}".format(i)) 


回答2:

If you want to get rid of the try, just ignore signals that cannot be caught.

#!/usr/bin/env python # https://stackoverflow.com/questions/2148888/python-trap-all-signals import os import sys import time import signal  SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \     for n in dir(signal) if n.startswith('SIG') and '_' not in n )   def receive_signal(signum, stack):     if signum in [1,2,3,15]:         print 'Caught signal %s (%s), exiting.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))         sys.exit()     else:         print 'Caught signal %s (%s), ignoring.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))  def main():     uncatchable = ['SIG_DFL','SIGSTOP','SIGKILL']     for i in [x for x in dir(signal) if x.startswith("SIG")]:         if not i in uncatchable:             signum = getattr(signal,i)             signal.signal(signum,receive_signal)     print('My PID: %s' % os.getpid())     while True:         time.sleep(1) main() 


回答3:

As of Python 3.5, the signal constants are defined as an enum, enabling a nicer approach:

import signal  catchable_sigs = set(signal.Signals) - {signal.SIGKILL, signal.SIGSTOP} for sig in catchable_sigs:     signal.signal(sig, print)  # Substitute handler of choice for `print` 


回答4:

Here's a 2/3 compatible way which doesn't have as many pitfalls as the others:

from itertools import count import signal  def set_all_signal_signals(handler):     """Set all signals to a particular handler."""     for signalnum in count(1):         try:             signal.signal(signalnum, handler)             print("set {}".format(signalnum))         except (OSError, RuntimeError):             # Invalid argument such as signals that can't be blocked             pass         except ValueError:             # Signal out of range             break 

Since signalnum is just a number, iterate over 1 to out of range setting the signal to a particular handle.



回答5:

That code won't work in the current version of python. There are many variables starting with SIG with the same value. For instance, SIGHUP and SIG_UNBLOCK are both 1. The only way I could think of to get a list of actual signals was to just make it myself.

from signal import *     signals = {         SIGABRT: 'SIGABRT',         SIGALRM: 'SIGALRM',         SIGBUS: 'SIGBUS',         SIGCHLD: 'SIGCHLD',         SIGCONT: 'SIGCONT',         SIGFPE: 'SIGFPE',         SIGHUP: 'SIGHUP',         SIGILL: 'SIGILL',         SIGINT: 'SIGINT',         SIGPIPE: 'SIGPIPE',         SIGPOLL: 'SIGPOLL',         SIGPROF: 'SIGPROF',         SIGQUIT: 'SIGQUIT',         SIGSEGV: 'SIGSEGV',         SIGSYS: 'SIGSYS',         SIGTERM: 'SIGTERM',         SIGTRAP: 'SIGTRAP',         SIGTSTP: 'SIGTSTP',         SIGTTIN: 'SIGTTIN',         SIGTTOU: 'SIGTTOU',         SIGURG: 'SIGURG',         SIGUSR1: 'SIGUSR1',         SIGUSR2: 'SIGUSR2',         SIGVTALRM: 'SIGVTALRM',         SIGXCPU: 'SIGXCPU',         SIGXFSZ: 'SIGXFSZ',         }  for num in signals:     signal(num, h) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!