examples example español python linux subprocess kill-process

example - Cómo terminar un subproceso python iniciado con shell=True



subprocess python español (9)

Como dijo Sai, el shell es el secundario, por lo que las señales son interceptadas por él; la mejor manera que he encontrado es usar shell = False y usar shlex para dividir la línea de comandos:

if isinstance(command, unicode): cmd = command.encode(''utf8'') args = shlex.split(cmd) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Entonces p.kill () y p.terminate () deberían funcionar como esperas.

Estoy lanzando un subproceso con el siguiente comando:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)

Sin embargo, cuando intento matar usando:

p.terminate()

o

p.kill()

El comando sigue ejecutándose en segundo plano, por lo que me preguntaba cómo puedo terminar el proceso.

Tenga en cuenta que cuando ejecuto el comando con:

p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)

Termina correctamente cuando se emite p.terminate() .


Cuando shell=True el shell es el proceso hijo y los comandos son sus hijos. Por lo tanto, cualquier SIGTERM o SIGKILL eliminará el shell pero no sus procesos secundarios, y no recuerdo una buena manera de hacerlo. La mejor manera que se me ocurra es usar shell=False , de lo contrario, cuando finalice el proceso de shell principal, dejará un proceso de shell difunto.


Enviar la señal a todos los procesos en grupo.

self.proc = Popen(commands, stdout=PIPE, stderr=STDOUT, universal_newlines=True, preexec_fn=os.setsid) os.killpg(os.getpgid(self.proc.pid), signal.SIGHUP) os.killpg(os.getpgid(self.proc.pid), signal.SIGTERM)


Ninguna de estas respuestas funcionó para mí, así que estoy dejando el código que funcionó. En mi caso, incluso después de finalizar el proceso con .kill() y obtener un código de retorno .poll() , el proceso no finalizó.

Siguiendo la documentation subprocess.Popen :

"... para limpiar correctamente, una aplicación que se comporte bien debe matar el proceso secundario y finalizar la comunicación ..."

proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()

En mi caso faltaba el proc.communicate() después de llamar proc.kill() . Esto limpia el proceso stdin, stdout ... y termina el proceso.


Sé que esta es una pregunta antigua, pero esto puede ayudar a alguien que busca un método diferente. Esto es lo que uso en Windows para matar procesos que he llamado.

si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call(["taskkill", "/IM", "robocopy.exe", "/T", "/F"], startupinfo=si)

/ IM es el nombre de la imagen, también puede hacer / PID si lo desea. / T mata el proceso así como los procesos secundarios. / F fuerza lo termina. Si, como lo tengo configurado, es cómo haces esto sin mostrar una ventana de CMD. Este código se utiliza en Python 3.


Si puedes usar psutil , entonces esto funciona perfectamente:

import subprocess import psutil def kill(proc_pid): process = psutil.Process(proc_pid) for proc in process.children(recursive=True): proc.kill() process.kill() proc = subprocess.Popen(["infinite_app", "param"], shell=True) try: proc.wait(timeout=3) except subprocess.TimeoutExpired: kill(proc.pid)


Utilice un grupo de proceso para permitir el envío de una señal a todo el proceso en los grupos. Para eso, debe adjuntar un ID de sesión al proceso principal de los procesos generados / secundarios, que es un shell en su caso. Esto lo convertirá en el líder de grupo de los procesos. Así que ahora, cuando se envía una señal al líder del grupo de procesos, se transmite a todos los procesos secundarios de este grupo.

Aquí está el código:

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


Yo podría hacerlo usando

from subprocess import Popen process = Popen(command, shell=True) Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))

mató el cmd.exe y el programa para el que di el comando.

(En Windows)


p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) p.kill()

p.kill() termina matando el proceso de shell y cmd todavía se está ejecutando.

He encontrado una solución conveniente a esto por:

p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)

Esto hará que cmd herede el proceso de shell, en lugar de que el shell inicie un proceso secundario, que no se elimina. p.pid será el ID de su proceso cmd entonces.

p.kill() debería funcionar.

Sin embargo, no sé qué efecto tendrá esto en tu tubería.