Given the following code:
try: subprocess.Popen(ExternalProcess, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True).communicate() except KeyboardInterrupt: exit(0)
If during the execution of ExternalProcess
(which is not a python script) one presses the Ctrl+C command, what exactly is going on?
Can I be sure for a 100% that in this scope, if I press the Ctrl+C, it will always get into the 'except' even if it happens during the execution of ExternalProcess
?
Or it depends on how the external process deals with it?
In Python, there is no special syntax for the KeyboardInterrupt exception; it is handled in the usual try and except block. The code that potentially causes the problem is written inside the try block, and the 'raise' keyword is used to raise the exception, or the python interpreter raises it automatically.
Interrupt from keyboard (CTRL + C). Default action is to raise KeyboardInterrupt .
subprocess. Process class is not thread safe. The Concurrency and multithreading in asyncio section.
Use Signal Handlers to Catch the KeyboardInterrupt Error in Python. The signal module is utilized to provide functions and mechanisms that use signal handlers in Python. We can catch the SIGINT signal, which is basically an interrupt from the keyboard Ctrl + C .
If the interpreter is running in an interactive session (i.e. by running python or python3 at the console), then the exception in the current function is printed and you return to the Python prompt.
Summary: in this tutorial, you’ll learn how to raise exceptions by using the Python raise statement. The ExceptionType () must be subclass of the BaseException class. Typically, it is a subclass of the Exception class. Note that the ExceptionType doesn’t need to be directly inherited from the Exception class.
It's because of the design of the Python interpreter and interactive session. Ctrl + C sends a signal, SIGINT, to the Python process, which the Python interpreter handles by raising the KeyboardInterrupt exception in the currently-running scope.
Now that you’re familiar with some of the very basics of starting new processes with the Python subprocess module, coming up you’ll see that you can run any kind of process, not just Python or text-based programs. With subprocess, you aren’t limited to text-based applications like the shell.
As far as I understand, once you fork/exec a process, it inherits the parent's process group. That means, that SIGINT
(which is the result of Ctrl+C and the cause of KeyboardInterrupt
) will be sent to both the child and the parent.
Here is an example:
File a.py
:
import subprocess try: subprocess.Popen("python b.py".split()).communicate() except KeyboardInterrupt: print "a.py got ctrl-c"
File b.py
try: while True: pass except KeyboardInterrupt: print "b.py got ctrl-c"
Now you run it and stop:
> python a.py ^Cb.py got ctrl-c a.py got ctrl-c
I assume you are using a Unix variant in my answer. I have no deeper knowledge about the Windows world.
If everything is configured normally, then the C-c
will be interpreted by the terminal (xterm, gnome-terminal, …). This terminal will send a SIGINT (see kill -l
to find out what your system's number for this is, typically it is 2) to all processes of the processgroup attached to the tty device associated with this terminal. That is either the shell or the program the shell started (and all its children because process groups get inherited).
A child can, however, leave its process group voluntarily and create a new one. Daemon processes typically do this to avoid being killed accidentally by a Ctrl-C pressed in the father program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With