You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按键终止os.system启动的子进程而不关闭主Python脚本?

解决方案:可控终止外部Python子进程

你当前用os.system()的问题在于,它会阻塞主进程且没法直接控制启动的子进程——一旦子进程进入无限循环,只能关闭整个主脚本才能停止它。改用subprocess模块就能解决这个问题,它允许你单独管理子进程的生命周期。

方案1:监听用户输入终止子进程

让用户输入指定字符(比如q)主动终止子进程,主脚本会持续运行直到子进程结束或用户触发终止:

import subprocess
import sys
import os

if os.path.isfile('../file'):
    # 构建绝对路径避免路径问题
    cmd_path = os.path.abspath('../file')
    # 启动子进程,继承主进程的输入输出
    child_proc = subprocess.Popen([sys.executable, cmd_path])

    print("子进程已启动,输入 'q' 并回车即可终止子进程")
    while True:
        # 检查子进程是否已自行结束
        if child_proc.poll() is not None:
            print("子进程已正常结束")
            break
        # 监听用户输入
        user_input = input().strip()
        if user_input.lower() == 'q':
            # 发送终止信号
            child_proc.terminate()
            # 等待子进程彻底退出
            child_proc.wait()
            print("子进程已被终止")
            break
    print('Process finished')

方案2:捕获Ctrl+C信号终止子进程

如果希望用户通过按下Ctrl+C终止子进程(而非关闭主脚本),可以监听系统信号并处理:

import subprocess
import sys
import os
import signal

# 定义信号处理函数
def handle_ctrl_c(sig, frame):
    # 如果子进程还在运行,先终止它
    if 'child_proc' in locals() and child_proc.poll() is None:
        child_proc.terminate()
        child_proc.wait()
        print("\n子进程已被终止")
    sys.exit(0)

# 注册Ctrl+C信号的处理函数
signal.signal(signal.SIGINT, handle_ctrl_c)

if os.path.isfile('../file'):
    cmd_path = os.path.abspath('../file')
    child_proc = subprocess.Popen([sys.executable, cmd_path])

    print("子进程已启动,按下 Ctrl+C 可终止子进程")
    # 等待子进程结束(无限循环时会卡在这,直到收到信号)
    child_proc.wait()
    print('Process finished')

关键说明

  • subprocess.Popen():启动子进程后立即返回进程对象,不会阻塞主进程,方便后续控制子进程。
  • proc.terminate():向子进程发送优雅终止信号(Unix下是SIGTERM,Windows下是CTRL_CLOSE_EVENT),若子进程无响应,可改用proc.kill()强制终止。
  • proc.poll():检查子进程状态,返回None表示仍在运行,返回退出码表示已结束。

内容的提问来源于stack exchange,提问作者PythonDudeLmao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:05:23