Hey everyone,



as I thought about writing the next post I came across the idea to explain what KeyboardInterrupt actually is and also how to catch it in Python 3.6.



KeyboardInterrupt is a User Signal which is executed by User. As an example could be pressing CTRL+C. In detail, the Signal is called SIGINT (Signal Interrupt). It could be useful catching a KeyboardInterrupt Signal to e.g. cleaning up temporary files which have been created during script execution.

Requirements

At first, we need to create a python script. Let’s name it ‘keyboardinterrupt.py’.

Catching SIGINT

Catching the SIGINT Signal may be useful for scripts or application which are multithreaded or when it’s necessary to be caught during the whole script execution.

Prerequisites

To catch the SIGINT it is required to import the signal library.

#!/usr/bin/env python3 import signal

Handler for the caught KeyboardInterrupt SIGINT

Now we need to add a function which is executed as soon as the SIGINT has been caught.

def keyboardInterruptHandler(signal, frame): print("KeyboardInterrupt (ID: {}) has been caught. Cleaning up...".format(signal)) exit(0)

As you can see, the function takes two positional arguments. The signal (integer) and the frame (object). The signal variable is an integer which represents the number of the caught signal. For SIGINT it’s the two (2). The frame variable represents the current Python stack frame which can be useful for debugging purposes.

Register a signal action

To execute a function before quitting the program you need to register an action.

signal.signal(signal.SIGINT, keyboardInterruptHandler)

Executing a long-running task

Now we’re executing a long-running task which will be interrupted by SIGINT.

while True: pass

Please note that the script will never end on it’s own.

Putting it all together

#!/usr/bin/env python3 import signal def keyboardInterruptHandler(signal, frame): print("KeyboardInterrupt (ID: {}) has been caught. Cleaning up...".format(signal)) exit(0) signal.signal(signal.SIGINT, keyboardInterruptHandler) while True: pass

When you run the script from above you will notice that nothing is happening. Just press CTRL+C and you will see the print output from the keyboardInterruptHandler function.

Running the script

[email protected]: python3 keyboardinterrupt.py <PRESS CTRL+C NOW!!!> ^CKeyboardInterrupt (ID: 2) has been caught. Cleaning up...

Catching KeyboardInterrupt exception

The second method reacting to is catching the KeyboardInterrupt exception. It can be useful in a script which is single threaded and also in long-running task situations which can be skipped but not canceling the whole script.

Prerequisites

We use the time library to simulate a running task. Therefore we’re importing it into a new file.

#!/usr/bin/env python3 import time

Adding a long-running task in a “try” block

We’re catching the KeyboardInterrupt exception with a “try-except” block.

try: while True: print("Heavy task!") time.sleep(2) except KeyboardInterrupt: print("KeyboardInterrupt has been caught.")

Putting it all together

#!/usr/bin/env python3 import time print("Calculating a lot... Can be canceled with CTRL+C") try: while True: print("Heavy task!") time.sleep(2) except KeyboardInterrupt: print("KeyboardInterrupt has been caught.") print("Continuing script execution")

As you can see i added some print information to add a hint to a user that the current task in the script can be skipped.

Running the script

[email protected]: python3 keyboardinterrupt.py Calculating a lot... Can be canceled with CTRL+C Heavy task! Heavy task! Heavy task! Heavy task! Heavy task! ^CKeyboardInterrupt has been caught. Continuing script execution

Conclusion

It’s very easy to implement signal catching in python 3.6. You can easily catch any kind of signal and react to it in a matching manner. As an example taken from dd (this is a unix program to convert and copy files) it is required to send USRSIG1 to the running process to show the current state of the progress.

Do you have any interesting ideas what to do with caught signals?

Further Ressources