python – How to kill a process Popen('start', shell=True)

Question:

Hey! I create a process in python

p = subprocess.Popen('start', shell=True)

But it's impossible to kill him from the code. I tried several options, but the console does not close

#1
p.kill()
#2
subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=p.pid))
#3
p.terminate()

Answer:

The .terminate() , .kill() methods of subprocess.Popen only try to stop the process itself:

#!/usr/bin/env python3
import subprocess
import sys
import time

start = time.monotonic()
process = subprocess.Popen([sys.executable or 'python', '-c',
                            'import time; time.sleep(30)'])
assert process.poll() is None  # process is alive
process.terminate()
process.wait()
assert (time.monotonic() - start) < 30  # exited before timeout
assert process.poll() is not None  # process is dead and reaped

At the same time, child processes can continue to live, for example .

By calling Popen() with the shell=True parameter, a process is implicitly created ( cmd.exe , /bin/sh ) that runs the given command. If it's not a builtin/internal command, then you have at least two processes (the shell itself plus the program it launched). .kill() kills the shell itself, while the child process can continue to live. On *nix, in this case, you can try to start the process in a separate process group and then send a signal to this group so that all processes terminate (similar to how Ctrl+C works in bash): How to terminate a python subprocess launched with shell=True . On Windows, you can try taskkill :

from subprocess import Popen, check_call

process = Popen('py -c "import time; time.sleep(30)"', shell=True)
check_call("TASKKILL /F /PID {pid} /T".format(pid=process.pid))

The /T argument says that taskkill attempts to kill both the process itself and any child processes it has started. Using the /IM option, you can stop processes by name.

psutil module provides a portable way to kill child processes .

To close the new window created by the start command upon completion of the child command, you can explicitly pass the /c option to cmd :

D:\> start /wait "title" cmd /c batch.cmd

You can add /B to start to prevent a new window from being created. If you used start to do something in the background, you don't need it in Python, just remove start ( Popen() call doesn't wait for the process to complete). Similarly, if you don't need the internal command to run, then shell=True can usually be dispensed with.

As an alternative to explicitly stopping, one can start processes in such a way that child processes are automatically killed when the parent terminates: Python: how to kill child process(es) when parent dies? On Windows, this can be done by assigning the created parent process to its Job object .

Scroll to Top