Estoy iniciando un subproceso con el siguiente comando:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Sin embargo, cuando trato de matar usando:
p.terminate()
o
p.kill()
El comando sigue ejecutándose en segundo plano, así que me preguntaba cómo puedo realmente terminar el proceso.
Tenga en cuenta que cuando ejecuto el comando con:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Se termina con éxito al emitir el p.terminate()
.
python
linux
subprocess
kill-process
usuario175259
fuente
fuente
cmd
aspecto? Puede contener un comando que desencadena varios procesos para iniciarse. Entonces no está claro de qué proceso hablas.shell=True
hecho una gran diferencia?Respuestas:
Utilice un grupo de procesos para permitir el envío de una señal a todo el proceso en los grupos. Para eso, debe adjuntar una identificación de sesión al proceso primario de los procesos generados / secundarios, que es un shell en su caso. Esto lo convertirá en el líder del grupo de los procesos. Entonces, 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:
fuente
os.setsid
no está disponible en Windows ( docs.python.org/library/os.html#os.setsid ), no sé si esto puede ayudar, pero puede mirar aquí ( bugs.python.org / número5115 ) para obtener información sobre cómo hacerlo.subprocess.CREATE_NEW_PROCESS_GROUP
relaciona con esto?CREATE_NEW_PROCESS_GROUP
se puede usar para emularstart_new_session=True
en Windowsp.kill()
termina matando el proceso de shell ycmd
todavía se está ejecutando.Encontré una solución conveniente para esto:
Esto hará que cmd herede el proceso de shell, en lugar de que el shell inicie un proceso hijo, que no se mata.
p.pid
será la identificación de su proceso de cmd entonces.p.kill()
Deberia trabajar.Sin embargo, no sé qué efecto tendrá esto en tu tubería.
fuente
Si puede usar psutil , entonces esto funciona perfectamente:
fuente
AttributeError: 'Process' object has no attribute 'get_children
parapip install psutil
.Podría hacerlo usando
mató al
cmd.exe
y al programa para el que le di la orden.(En Windows)
fuente
Popen("TASKKILL /F /IM " + process_name)
si no lo tiene, puede obtenerlo delcommand
parámetro.Cuando
shell=True
el shell es el proceso hijo, y los comandos son sus hijos. Entonces cualquieraSIGTERM
oSIGKILL
matará el shell pero no sus procesos hijos, y no recuerdo una buena manera de hacerlo. La mejor manera en que puedo pensar es en usarshell=False
, de lo contrario, cuando elimine el proceso de shell principal, dejará un proceso de shell inactivo.fuente
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
.kill()
y obtener un.poll()
código de retorno, el proceso no finalizó.Siguiendo la
subprocess.Popen
documentación :En mi caso, me faltaba el
proc.communicate()
después de llamarproc.kill()
. Esto limpia el proceso stdin, stdout ... y termina el proceso.fuente
Como dijo Sai, el shell es el niño, 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 comando:
Entonces p.kill () y p.terminate () deberían funcionar como espera.
fuente
cwd
argumento aPopen
.lo que siento que podríamos usar:
esto no matará toda su tarea sino el proceso con el p.pid
fuente
Sé que esta es una vieja pregunta, pero puede ayudar a alguien que busca un método diferente. Esto es lo que uso en Windows para eliminar los procesos que he llamado.
/ IM es el nombre de la imagen, también puede hacer / PID si lo desea. / T mata tanto el proceso como los procesos secundarios. / F fuerza lo termina. si, como lo tengo configurado, es cómo hacer esto sin mostrar una ventana CMD. Este código se usa en python 3.
fuente
Enviar la señal a todos los procesos en grupo
fuente
No he visto esto mencionado aquí, así que lo estoy publicando en caso de que alguien lo necesite. Si todo lo que quiere hacer es asegurarse de que su subproceso finalice correctamente, puede ponerlo en un administrador de contexto. Por ejemplo, quería que mi impresora estándar imprimiera una imagen y al usar el administrador de contexto me aseguré de que el subproceso terminara.
Creo que este método también es multiplataforma.
fuente
shell=True
, según la pregunta? Que no está en tu código.thread.join()
. Espero que esto lo aclare.