Penso di averlo capito, il problema era che se l'avessi fatto
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))
ucciderebbe il processo che ha avviato l'interprete python
>>> Terminated
quindi, invece, ho impostato 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))
in un'altra shell, se controllo
pgrep sleep
non viene visualizzato nulla, quindi viene effettivamente ucciso.
Ho avuto lo stesso problema con il sottoprocesso root ma le risposte qui e qui- Python come uccidere il sottoprocesso root non ha funzionato per me.
Alla fine l'unica cosa che ha funzionato è stata:
proc = subprocess.Popen(["sudo", exe_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
.
.
.
os.system("sudo pkill -9 -P " + str(proc.pid))
Senza la necessità di preexec_fn=os.setpgrp
Quando esegui pgrep sleep
ti viene mostrato il PID del sleep
comando, eseguito come figlio di sudo
processo che hai creato.
Come demo veloce, ho salvato quanto segue come subproc.py
:
import subprocess
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
Durante l'esecuzione di questo script, possiamo vedere due processi generati:
~/$ python subproc.py
Process spawned with PID: 5296
~/$ ps all | grep sleep
0 5296 1 sudo sleep 100
0 5297 5296 sleep 100
Noterai che il PID che conosci nel tuo codice è il processo sudo "genitore". Questo è il processo che dovresti terminare, ma dovrai usare sudo per farlo:
subprocess.check_call(["sudo", "kill", str(pr.pid)])
#You might want to wait for the process to end:
os.waitpid(pr.pid, 0)