如何按键终止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
相关产品推荐
相关产品推荐

