import asyncio import logging import uuid async def call(command, timeout=300): command_excute_id = uuid.uuid4().hex process = await asyncio.create_subprocess_shell( command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) async def kill_proc(): await asyncio.sleep(timeout) process.kill() logging.info("[%s] process timeout, killed.", command_excute_id) return await process.communicate() killer = asyncio.create_task(kill_proc()) stdout, stderr = "", "" await process.wait() stdout, stderr = await process.communicate() if not killer.done(): killer.cancel() else: stdout, stderr = killer.result() returncode = process.returncode if returncode != 0: logging.error("[%s] command failed: %s", command_excute_id, command) logging.error("[%s] stderr: %s", command_excute_id, stderr) logging.error("[%s] stdout: %s", command_excute_id, stdout) return returncode, stdout, stderr async def main(): r = await call("echo 'hello' && sleep 0.4 && echo 'fine!'", timeout=1) print("info", r) if __name__ == "__main__": asyncio.run(main())