Python: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT Python: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT python python

Python: How to prevent subprocesses from receiving CTRL-C / Control-C / SIGINT


Somebody in the #python IRC-Channel (Freenode) helped me by pointing out the preexec_fn parameter of subprocess.Popen(...):

If preexec_fn is set to a callable object, this object will be called in the child process just before the child is executed. (Unix only)

Thus, the following code solves the problem (UNIX only):

import subprocessimport signaldef preexec_function():    # Ignore the SIGINT signal by setting the handler to the standard    # signal handler SIG_IGN.    signal.signal(signal.SIGINT, signal.SIG_IGN)my_process = subprocess.Popen(    ["my_executable"],    preexec_fn = preexec_function)

Note: The signal is actually not prevented from reaching the subprocess. Instead, the preexec_fn above overwrites the signal's default handler so that the signal is ignored. Thus, this solution may not work if the subprocess overwrites the SIGINT handler again.

Another note: This solution works for all sorts of subprocesses, i.e. it is not restricted to subprocesses written in Python, too. For example the dedicated server I am writing my wrapper for is in fact written in Java.


Combining some of other answers that will do the trick - no signal sent to main app will be forwarded to the subprocess.

import osfrom subprocess import Popendef preexec(): # Don't forward signals.    os.setpgrp()Popen('whatever', preexec_fn = preexec)


you can do something like this to make it work in windows and unix:

import subprocessimport sysdef pre_exec():    # To ignore CTRL+C signal in the new process    signal.signal(signal.SIGINT, signal.SIG_IGN)if sys.platform.startswith('win'):    #https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx    #CREATE_NEW_PROCESS_GROUP=0x00000200 -> If this flag is specified, CTRL+C signals will be disabled    my_sub_process=subprocess.Popen(["executable"], creationflags=0x00000200)else:    my_sub_process=subprocess.Popen(["executable"], preexec_fn = pre_exec)