How do I capture SIGINT in Python?

python catch sigint
python keyboardinterrupt
python catch ctrl-c windows
python send signal to thread
python interrupt function
python catch ctrl-c exception
python signal handler arguments
python siginfo

I'm working on a python script that starts several processes and database connections. Every now and then I want to kill the script with a Ctrl+C signal, and I'd like to do some cleanup.

In Perl I'd do this:

$SIG{'INT'} = 'exit_gracefully';

sub exit_gracefully {
    print "Caught ^C \n";
    exit (0);
}

How do I do the analogue of this in Python?

Register your handler with signal.signal like this:

#!/usr/bin/env python
import signal
import sys

def signal_handler(sig, frame):
    print('You pressed Ctrl+C!')
    sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
signal.pause()

Code adapted from here.

More documentation on signal can be found here.  

Python Catch SIGINT (CTRL-C), the KeyboardInterrupt exception. You can implement any clean-up code in the exception handler. You can use the functions in Python’s built-in signal module to set up signal handlers in python. Specifically the signal.signal (signalnum, handler) function is used to register the handler function for signal signalnum.

You can treat it like an exception (KeyboardInterrupt), like any other. Make a new file and run it from your shell with the following contents to see what I mean:

import time, sys

x = 1
while True:
    try:
        print x
        time.sleep(.3)
        x += 1
    except KeyboardInterrupt:
        print "Bye"
        sys.exit()

command line, interpreter handles by raising the KeyboardInterrupt exception in the currently-running scope. import signal. import sys. def signal_handler (sig, frame): print ('You pressed Ctrl+C!') sys.exit (0) signal.signal (signal.SIGINT, signal_handler) print ('Press Ctrl+C') signal.pause () Please log in or register to add a comment.

And as a context manager:

import signal

class GracefulInterruptHandler(object):

    def __init__(self, sig=signal.SIGINT):
        self.sig = sig

    def __enter__(self):

        self.interrupted = False
        self.released = False

        self.original_handler = signal.getsignal(self.sig)

        def handler(signum, frame):
            self.release()
            self.interrupted = True

        signal.signal(self.sig, handler)

        return self

    def __exit__(self, type, value, tb):
        self.release()

    def release(self):

        if self.released:
            return False

        signal.signal(self.sig, self.original_handler)

        self.released = True

        return True

To use:

with GracefulInterruptHandler() as h:
    for i in xrange(1000):
        print "..."
        time.sleep(1)
        if h.interrupted:
            print "interrupted!"
            time.sleep(2)
            break

Nested handlers:

with GracefulInterruptHandler() as h1:
    while True:
        print "(1)..."
        time.sleep(1)
        with GracefulInterruptHandler() as h2:
            while True:
                print "\t(2)..."
                time.sleep(1)
                if h2.interrupted:
                    print "\t(2) interrupted!"
                    time.sleep(2)
                    break
        if h1.interrupted:
            print "(1) interrupted!"
            time.sleep(2)
            break

From here: https://gist.github.com/2907502

Signal (IPC), ); by default, this causes the process to terminate. Ctrl-Z sends a TSTP signal ("terminal stop", SIGTSTP); by default, this causes the process to suspend execution. Restore the original SIGINT handler in the parent process after a Pool has been created. Use map_async and apply_async instead of blocking map and apply. Wait on the results with timeout because the default blocking waits to ignore all signals. This is Python bug https://bugs.python.org/issue8296.

You can handle CTRL+C by catching the KeyboardInterrupt exception. You can implement any clean-up code in the exception handler.

signal — Set handlers for asynchronous events, This is one of two standard signal handling options; it will simply perform the SIGHUP ; the variable names are identical to the names used in C programs, as  A more robust way is to capture the SIGINT signal raised by jupyter on interrupt. As Matt J writes here, this can be accomplished using the signal library.

From Python's documentation:

import signal
import time

def handler(signum, frame):
    print 'Here you go'

signal.signal(signal.SIGINT, handler)

time.sleep(10) # Press Ctrl+c here

How do I capture SIGINT in Python?, There are many ways to solve this problem but I am mentioning the most preferable and important way:- The first thing you have to register your  Take the attached Python file issue18040.py and run "c:\pythonxx\python.exe -i issue18040.py" for any version of Python from 2.4 to 3.4. At the interpreter prompt, pressing Ctrl-C produces "Keyboard Interrupt" consistently (except for the few times it exits the interpreter which is the problem fixed in issue1677 ).

Handling Unix Signals in Python, Handling Unix Signals in Python kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1​  Set the handler for signal signalnum to the function handler. handler can be a callable Python object taking two arguments (see below), or one of the special values signal.SIG_IGN or signal.SIG_DFL. The previous signal handler will be returned (see the description of getsignal () above).

Handle CTRL+C in Python · GitHub, handle-ctrl-c.py. #!/usr/bin/env python. import signal. import sys. def signal_handler(signal, frame):. sys.exit(0). signal.signal(signal.SIGINT  Set the handler for signal signalnum to the function handler. handler can be a callable Python object taking two arguments (see below), or one of the special values signal.SIG_IGN or signal.SIG_DFL. The previous signal handler will be returned (see the description of getsignal() above). (See the Unix man page signal(2).)

How do I capture SIGINT in Python?, Im working on a python script that starts several processes and database connections Every now and then I want to kill the script with a There is also a search page for a number of sources of Python-related information. Failing that, just Google for a phrase including the word ''python'' and you may well get the result you need. If all else fails, ask on the python newsgroup and there's a good chance someone will put you on the right track.

Comments
  • Could you tell me why to use this in stead of a KeyboardInterrupt exception? Isn't that more intuitive to use?
  • Noio: 2 reasons. First, SIGINT can be sent to your process any number of ways (e.g., 'kill -s INT <pid>'); I'm not sure if KeyboardInterruptException is implemented as a SIGINT handler or if it really only catches Ctrl+C presses, but either way, using a signal handler makes your intent explicit (at least, if your intent is the same as OP's). More importantly though, with a signal you don't have to wrap try-catches around everything to make them work, which can be more or less of a composability and general software engineering win depending on the structure of your application.
  • Example of why you want to trap the signal instead of catch the Exception. Say you run your program and redirect the output to a log file, ./program.py > output.log. When you press Ctrl-C you want your program to exit gracefully by having it log that all data files have been flushed and marked clean to confirm they are left in a known good state. But Ctrl-C sends SIGINT to all processes in a pipeline, so the shell may close STDOUT (now "output.log") before program.py finishes printing the final log. Python will complain, "close failed in file object destructor: Error in sys.excepthook:".
  • Note that signal.pause() is unavailable on Windows. docs.python.org/dev/library/signal.html
  • -1 unicorns for using signal.pause(), suggests that I would have to wait at such a blocking call instead of doing some real work. ;)
  • Attention when using this solution. You should use also this code before KeyboardInterrupt catch block: signal.signal(signal.SIGINT, signal.default_int_handler), or you're going to fail, because KeyboardInterrupt does not fire in every situation in which it should fire! Details are here.
  • It could also throw a StopIteration to break the innermost loop when a ctrl-C is pressed, right?
  • @TheoBelaire Instead of just throwing a StopIteration, I would create a generator that accepts an iterable as a parameter and registers/releases the signal handler.
  • You should only use except for stuff that isn't supposed to happen. In this case KeyboardInterrupt is supposed to happen. So this is not a good construction.
  • @TristanT In any other language yes, but in Python exceptions are not just for things that are not supposed to happen. It is actually considered good style in Python to use exceptions for flow control (where appropriate).
  • You should use an event or time.sleep() instead of doing a busy loop on a variable.
  • @OlivierM This is really application specific and definitely not the point of this example. For example, blocking calls or await functions won't keep the CPU busy. Furthermore, this is just an example of how things can be done. KeyboardInterrupts are often enough, like mentioned in other answers.