Python中如何读取新命令提示符窗口的输出?
解决方案:在新CMD窗口运行EXE并捕获输出
问题分析
核心问题在于:使用subprocess.CREATE_NEW_CONSOLE创建独立控制台窗口时,子进程的输出会直接绑定到新窗口,无法通过stdout=subprocess.PIPE直接捕获;同时原代码的命令字符串存在引号转义错误,导致程序无法正常启动。
关键原因
CREATE_NEW_CONSOLE会为子进程生成独立的控制台会话,其标准输出默认指向该新窗口,而非父进程的管道。- 使用
shell=True时,命令字符串的引号转义逻辑易出错,推荐用列表形式传递参数规避解析问题。
解决方案1:同时显示新窗口输出并捕获(临时文件中转)
通过将EXE输出重定向到临时文件,同时在新窗口显示内容,父进程再读取临时文件获取输出,兼顾显示和捕获需求:
import os import tempfile import subprocess from subprocess import CREATE_NEW_CONSOLE import time def OpenServers(): currentDirectory = os.path.dirname(os.path.abspath(__file__)) coreServerFullPath = os.path.join(currentDirectory, "Core\\CoreServer\\Server\\CoreServer/bin\\Debug") echoServerFullPath = os.path.join(currentDirectory, "Echo\\Server\\EchoServer/bin\\Debug") # 处理CoreServer:输出到临时文件+在新窗口显示 with tempfile.NamedTemporaryFile(mode='w+', delete=False, encoding='utf-8') as temp_core: temp_core_path = temp_core.name core_cmd = [ 'cmd.exe', '/K', f'CoreServer.exe -c -s > "{temp_core_path}" 2>&1 && type "{temp_core_path}"' ] # 用cwd参数指定工作目录,避免全局切换路径 cmd = subprocess.Popen( core_cmd, creationflags=CREATE_NEW_CONSOLE, cwd=coreServerFullPath ) time.sleep(3) # 等待程序启动并输出内容 # 读取CoreServer的输出 with open(temp_core_path, 'r', encoding='utf-8') as f: core_output = f.read() print("CoreServer 输出:\n", core_output) os.unlink(temp_core_path) # 清理临时文件 # 处理EchoServer,逻辑同上 with tempfile.NamedTemporaryFile(mode='w+', delete=False, encoding='utf-8') as temp_echo: temp_echo_path = temp_echo.name echo_cmd = [ 'cmd.exe', '/K', f'EchoServer.exe -c -s > "{temp_echo_path}" 2>&1 && type "{temp_echo_path}"' ] cmd1 = subprocess.Popen( echo_cmd, creationflags=CREATE_NEW_CONSOLE, cwd=echoServerFullPath ) time.sleep(1) with open(temp_echo_path, 'r', encoding='utf-8') as f: echo_output = f.read() print("EchoServer 输出:\n", echo_output) os.unlink(temp_echo_path)
解决方案2:仅捕获输出(新窗口无显示)
如果不需要在新窗口显示内容,仅需捕获输出,可直接将EXE的stdout/stderr重定向到管道:
cmd = subprocess.Popen( ['CoreServer.exe', '-c', '-s'], creationflags=CREATE_NEW_CONSOLE, cwd=coreServerFullPath, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True # 以文本模式读取,无需处理二进制数据 ) # 读取输出(若为持续输出,建议用循环逐行读取) core_output = cmd.stdout.read() print("CoreServer 输出:\n", core_output)
代码优化点
- 使用
cwd参数指定子进程工作目录,替代os.chdir,避免影响全局路径状态。 - 采用列表形式传递命令参数,规避
shell=True带来的解析风险和引号问题。 - 用临时文件中转输出,同时满足新窗口显示和父进程捕获的需求。
内容的提问来源于stack exchange,提问作者nikhil
相关产品推荐
相关产品推荐

