Je pense que j'ai compris, le problème était que si je faisais ça
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))
cela tuerait le processus qui a démarré l'interpréteur python
>>> Terminated
donc à la place, j'ai mis le preexec_fn
à 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))
dans un autre shell, si je coche
pgrep sleep
rien ne s'affiche, il est donc réellement tué.
J'ai eu le même problème avec le sous-processus racine mais les réponses ici et ici - Python comment tuer le sous-processus racine n'a pas fonctionné pour moi.
À la fin, la seule chose qui fonctionnait était :
proc = subprocess.Popen(["sudo", exe_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
.
.
.
os.system("sudo pkill -9 -P " + str(proc.pid))
Sans avoir besoin de - preexec_fn=os.setpgrp
Lorsque vous exécutez pgrep sleep
on vous montre le PID du sleep
commande, s'exécutant en tant qu'enfant du sudo
processus que vous avez créé.
En guise de démonstration rapide, j'ai enregistré ce qui suit sous le nom subproc.py
:
import subprocess
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
Lors de l'exécution de ce script, nous pouvons voir apparaître deux processus :
~/$ python subproc.py
Process spawned with PID: 5296
~/$ ps all | grep sleep
0 5296 1 sudo sleep 100
0 5297 5296 sleep 100
Vous remarquerez que le PID que vous connaissez dans votre code est le processus sudo 'parent'. C'est le processus que vous devriez tuer, mais vous devrez utiliser sudo pour le faire :
subprocess.check_call(["sudo", "kill", str(pr.pid)])
#You might want to wait for the process to end:
os.waitpid(pr.pid, 0)