Killing sudo-started subprocess in python
I think I figured it out, the issue was that if I did this
import subprocess, os
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
pgid = os.getpgid(pr.pid)
subprocess.check_output("sudo kill {}".format(pgid))
it would kill the process that started the python interpreter
>>> Terminated
so instead, I set the preexec_fn
to os.setpgrp
import subprocess, os
pr = subprocess.Popen(["sudo", "sleep", "100"], preexec_fn=os.setpgrp)
print("Process spawned with PID: %s" % pr.pid)
pgid = os.getpgid(pr.pid)
subprocess.check_output("sudo kill {}".format(pgid))
in another shell, if I check
pgrep sleep
nothing shows up, so it is actually killed.
I had the same problem with root subprocess but the answers here and here- Python how to kill root subprocess did not worked for me.
At the end the only thing that worked was:
proc = subprocess.Popen(["sudo", exe_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
.
.
.
os.system("sudo pkill -9 -P " + str(proc.pid))
Without the need for- preexec_fn=os.setpgrp
When you execute pgrep sleep
you are shown the PID of the sleep
command, running as a child of the sudo
process you created.
As a quick demo, I saved the following as subproc.py
:
import subprocess
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
When running this script, we can see two processes spawned:
~/$ python subproc.py
Process spawned with PID: 5296
~/$ ps all | grep sleep
0 5296 1 sudo sleep 100
0 5297 5296 sleep 100
You'll notice that the PID you know about in your code is the 'parent' sudo process. This is the process you should kill, but you'll need to use sudo to do it:
subprocess.check_call(["sudo", "kill", str(pr.pid)])
#You might want to wait for the process to end:
os.waitpid(pr.pid, 0)