Creo que lo descubrí, el problema era que si hacía esto
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))
mataría el proceso que inició el intérprete de python
>>> Terminated
entonces, en cambio, configuré el preexec_fn
a 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))
en otro caparazón, si compruebo
pgrep sleep
no aparece nada, por lo que en realidad se elimina.
Tuve el mismo problema con el subproceso raíz, pero las respuestas aquí y aquí:Python, cómo eliminar el subproceso raíz, no funcionó para mí.
Al final lo único que funcionó fue:
proc = subprocess.Popen(["sudo", exe_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
.
.
.
os.system("sudo pkill -9 -P " + str(proc.pid))
Sin necesidad de preexec_fn=os.setpgrp
Cuando ejecutas pgrep sleep
se le muestra el PID del sleep
comando, ejecutándose como un hijo del sudo
proceso que ha creado.
Como demostración rápida, guardé lo siguiente como subproc.py
:
import subprocess
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
Al ejecutar este script, podemos ver dos procesos generados:
~/$ python subproc.py
Process spawned with PID: 5296
~/$ ps all | grep sleep
0 5296 1 sudo sleep 100
0 5297 5296 sleep 100
Notará que el PID que conoce en su código es el proceso sudo 'principal'. Este es el proceso que debe eliminar, pero deberá usar Sudo para hacerlo:
subprocess.check_call(["sudo", "kill", str(pr.pid)])
#You might want to wait for the process to end:
os.waitpid(pr.pid, 0)