如何避免subprocess.Popen启动的CMD窗口因异常抛出而关闭?
解决Windows下subprocess启动CMD窗口报错后自动关闭的问题
针对你遇到的脚本抛出异常时CMD窗口直接关闭、无法查看错误信息的问题,我整理了两种对应你需求的解决方案:
方案一:让子窗口始终保持打开(无论是否报错)
这个方案的核心是确保input()语句一定会被执行,哪怕脚本运行出错。我们可以用try-except-finally结构包裹业务逻辑,捕获所有异常并打印详细错误信息,最后在finally块中强制执行input(),这样无论脚本成功还是失败,窗口都会等待用户按下回车才关闭。
修改后的完整代码:
import sys import platform from subprocess import Popen pipelines = [("Name1","path1"), ("Name2","path2")] # 定义启动新终端的命令(Windows下) if platform.system() == "Windows": new_window_command = "cmd.exe /c start".split() else: new_window_command = "x-terminal-emulator -e".split() processes = [] for name, script_path in pipelines: # 修改Python命令,加入异常捕获和确保input执行的逻辑 python_cmd = ( "import sys; print(f'运行脚本:{name}'); " "try: " f"from {script_path} import {name}; obj = {name}(); obj.run(); " "print('脚本运行成功!'); " "except Exception as e: " "print(f'脚本运行失败:{str(e)}'); " "import traceback; traceback.print_exc(); # 打印详细错误栈,方便排查" "finally: " "input('按Enter键关闭窗口..');" ) echo = [sys.executable, "-c", python_cmd] processes.append(Popen(new_window_command + echo)) for proc in processes: proc.wait()
关键优化点:
- 用
try-except捕获所有异常,同时打印错误栈,能帮你快速定位问题 finally块强制触发input(),彻底避免窗口因异常直接关闭- 新增成功提示,让用户清晰知晓脚本的运行状态
方案二:将错误信息返回至主窗口
如果希望主窗口统一处理错误提示,子窗口可选择关闭或短暂停留,我们可以让子脚本把错误信息写入临时文件,主进程在子任务结束后读取并展示这些内容。
修改后的完整代码:
import sys import platform import os from subprocess import Popen pipelines = [("Name1","path1"), ("Name2","path2")] # 定义启动新终端的命令(Windows下) if platform.system() == "Windows": new_window_command = "cmd.exe /c start".split() else: new_window_command = "x-terminal-emulator -e".split() processes = [] error_files = [] for idx, (name, script_path) in enumerate(pipelines): # 为每个任务创建唯一的错误文件,避免内容冲突 error_file = f"temp_error_{idx}.txt" error_files.append(error_file) python_cmd = ( "import sys, traceback; print(f'运行脚本:{name}'); " "try: " f"from {script_path} import {name}; obj = {name}(); obj.run(); " "print('脚本运行成功!'); " "except Exception as e: " f"with open('{error_file}', 'w') as f: " "f.write(f'脚本【{name}】运行失败:\\n'); " "f.write(f'错误信息:{str(e)}\\n'); " "f.write('详细错误栈:\\n'); " "f.write(traceback.format_exc()); " "print('脚本运行失败,错误信息已返回主窗口'); " "input('按Enter键关闭窗口..');" ) echo = [sys.executable, "-c", python_cmd] processes.append(Popen(new_window_command + echo)) # 等待所有子进程结束,然后读取并展示错误信息 for proc, error_file in zip(processes, error_files): proc.wait() if os.path.exists(error_file): print(f"\n===== 脚本错误报告 =====") with open(error_file, 'r') as f: print(f.read()) os.remove(error_file) # 清理临时文件,避免冗余
关键优化点:
- 为每个子任务生成唯一的临时错误文件,防止多任务之间的信息覆盖
- 子脚本捕获异常后,将错误信息和详细栈追踪写入文件
- 主进程统一收集并展示错误报告,最后自动清理临时文件
- 子窗口保留
input()让用户确认,也可根据需求删除该语句,让窗口自动关闭
内容的提问来源于stack exchange,提问作者Tamás Majszlinger
相关产品推荐
相关产品推荐

