Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

487
Vistas
Kill a python subprocess that does not return

TLDR I want to kill a subprocess like top while it is still running
I am using Fastapi to run a command on input. For example if I enter top my program runs the command but since it does not return, at the moment I have to use a time delay then kill/terminate it. However I want to be able to kill it while it is still running. However at the moment it won't run my kill command until the time runs out. Here is the current code for running a process:

@app.put("/command/{command}")
async def run_command(command: str):
    subprocess.run([command], shell=True, timeout=10)
    return {"run command"}

and to kill it

@app.get("/stop")
async def stop():
    proc.kill()
    return{"Stop"}

I am new to fastapi so I would be grateful for any help

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

It's because subprocess.run is blocking itself - you need to run shell command in background e.g. if you have asnycio loop already on, you could use subprocesses

import asyncio

process = None
@app.get("/command/{command}")
async def run_command(command: str):
    global process
    process = await asyncio.create_subprocess_exec(
        command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )
    return {"run command"}

@app.get("/stop")
async def stop():
    process.kill()
    return {"Stop"}

Or with Popen

from subprocess import Popen

process = None
@app.get("/command/{command}")
async def run_command(command: str):
    global process
    process = Popen([command])  # something long running
    return {"run command"}

Adding the timeout option can be tricky as you do not want to wait until it completes (where you could indeed use wait_for function) but rather kill process after specific time. As far I know the best option would be to schedule other process which is responsible for killing main one. The code with asyncio could look like that:

@app.get("/command/{command}")
async def run_command(command: str):
    global process
    process = await asyncio.create_subprocess_exec(
        command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )
    loop = asyncio.get_event_loop()
    # We schedule here stop coroutine execution that runs after TIMEOUT seconds
    loop.call_later(TIMEOUT, asyncio.create_task, stop(process.pid))

    return {"run command"}

@app.get("/stop")
async def stop(pid=None):
    global process
    # We need to make sure we won't kill different process
    if process and (pid is None or process.pid == pid):
        process.kill()
        process = None
    return {"Stop"}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda