Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

225
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda