How to terminate a python subprocess launched with shell=True
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Digital Sunset Looping
--
Chapters
00:00 Question
00:48 Accepted answer (Score 518)
01:38 Answer 2 (Score 130)
02:16 Answer 3 (Score 91)
02:40 Answer 4 (Score 40)
03:00 Thank you
--
Full question
https://stackoverflow.com/questions/4789...
Accepted answer links:
[process group]: http://en.wikipedia.org/wiki/Process_gro...
[session id]: http://pubs.opengroup.org/onlinepubs/009...
Answer 3 links:
[psutil]: https://pypi.python.org/pypi/psutil/
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #linux #subprocess #killprocess
#avk47
ACCEPTED ANSWER
Score 554
Use a process group so as to enable sending a signal to all the process in the groups. For that, you should attach a session id to the parent process of the spawned/child processes, which is a shell in your case. This will make it the group leader of the processes. So now, when a signal is sent to the process group leader, it's transmitted to all of the child processes of this group.
Here's the code:
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # Send the signal to all the process groups
ANSWER 2
Score 142
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
p.kill()
p.kill() ends up killing the shell process and cmd is still running.
I found a convenient fix this by:
p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)
This will cause cmd to inherit the shell process, instead of having the shell launch a child process, which does not get killed. p.pid will be the id of your cmd process then.
p.kill() should work.
I don't know what effect this will have on your pipe though.
ANSWER 3
Score 43
I could do it using
from subprocess import Popen
process = Popen(command, shell=True)
Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
it killed the cmd.exe and the program that i gave the command for.
(On Windows)
ANSWER 4
Score 21
When shell=True the shell is the child process, and the commands are its children. So any SIGTERM or SIGKILL will kill the shell but not its child processes, and I don't remember a good way to do it.
The best way I can think of is to use shell=False, otherwise when you kill the parent shell process, it will leave a defunct shell process.