Python 在退出时关闭自己的 CMD shell 窗口

Ste*_*Buk 6 python windows cmd

我正在运行多个进程(数百个),每个进程都在 python 中并使用以下方法调用:

command = 'start cmd /k call python %s' % (some_py_prog)
os.system(command)
Run Code Online (Sandbox Code Playgroud)

/k 在执行后使 cmd 窗口保持打开状态。这有助于检查错误。然而,当我调用数百个工作时,我的屏幕变得杂乱无章。

那么如何让python仅在成功完成时关闭它自己的主机cmd窗口?我需要错误的工作保持可见。

Ser*_*sta 6

简短回答:只要使用/c而不是/k会导致 cmd 脚本在命令终止后立即退出,这就是您所要求的:

command = 'start cmd /c call python %s' % (some_py_prog)
os.system(command)
Run Code Online (Sandbox Code Playgroud)

但是你在cmd.exe这里堆叠了一些不必要的东西:一个用于os.system调用,一个用于显式cmd.c. 您可以简单地使用该subprocess模块:

subprocess.call('python %s' % (some_py_prog), 
    creationflags = subprocess.CREATE_NEW_CONSOLE)
Run Code Online (Sandbox Code Playgroud)

创建标志足以要求系统在新控制台中启动新进程,该新控制台将在命令终止后立即关闭。可选地,shell=True如果您需要它来预处理一些 cmd 好东西,例如 io 重定向,您可以添加该选项。

(更多细节来自我的其他答案,特别是在 eryksun 的评论中)


Mof*_*ofi 4

让我们首先分析一下发布的两行 Python 脚本行在执行 Python 脚本时到底做了什么。感谢eryksun使用 Python 进行的深入调查,得出了正确的描述,现在可以在下面阅读。

\n\n

os.system()导致在控制台窗口中在前台执行cmd.exe /C,并停止执行 Python 脚本,直到 Windows 命令解释器终止。如果Python脚本本身是在控制台中执行的,则startedcmd.exe会继承该控制台。

\n\n

该命令进程以 开始start,这是 的一个内部命令cmd.exe,还有一个带有前台控制台窗口的命令进程。很好,但是第二个命令进程在完成命令执行后立即终止。如果您想查看执行的脚本或 Python 解释器本身在运行 Python 脚本时输出的错误,那么这不太好。

\n\n

因此,第二个命令进程以继续运行此命令进程cmd.exe的选项开始/k,该命令进程继承创建的控制台start,并在完成指定命令的执行后打开控制台窗口。

\n\n

第二个命令进程运行call根本没有必要的内部命令,因为python它实际上是python.exe控制台应用程序而不是批处理文件。因此call根本不需要。

\n\n

建议始终指定应用程序和脚本的完整文件名,即文件名+文件扩展名,而不仅仅是文件名。如果可执行文件/脚本的路径已知且固定,则也应指定它。这使得应用程序/脚本的执行独立于当前目录和环境变量PATHEXT以及PATH.

\n\n

Python解释器在第二个控制台中执行指定的Python脚本。

\n\n

启动的第一个命令进程在完成os.system()后立即终止,这在解释 Python 脚本时start启动后就已经发生了。cmd.exe /kpython.exe

\n\n

剩下的就是使用脚本运行 Python 解释器的第二个命令进程。即使Python解释器在执行完\xc2\xa0指定的Python脚本后终止,该命令进程仍继续运行。

\n\n

因此,目标是一旦 Python 解释器完成 Python 脚本的执行,也终止带有控制台窗口的第二个命令进程,但前提是在执行 \xc2\xa0 脚本时没有发生错误。

\n\n

好吧,我根本没有安装 Python,但我想它在执行脚本时出错时会以大于 0 的返回码退出。否则,成功执行脚本时退出代码为 0。

\n\n

所以使用这样的命令可能会起作用:

\n\n
command = \'start cmd.exe /K python.exe %s ^&^& exit\' % (some_py_prog)\nos.system(command)\n
Run Code Online (Sandbox Code Playgroud)\n\n

由第二个命令进程启动的命令行start cmd.exe /K现在包含两个命令:

\n\n
    \n
  1. Python 解释器python.exe,其脚本作为参数执行
    \nand
  2. \n
  3. 内部命令,仅当第一个命令的退出代码是由于操作员时,exitWindows命令解释器才应执行第二个命令。0&&
  4. \n
\n\n

有关要执行多个命令的单个命令行的详细信息,请参阅使用 Windows 批处理文件的单行多个命令的答案。

\n\n

每个 & 符号必须使用 Windows 命令解释器的转义字符(即插入符号)进行转义^。这是必要的,否则&&第一个命令进程将被解释start为成功执行后运行的附加命令start

\n\n

请注意,我没有安装 Python,因此仅使用Test.bat带有单个命令行的批处理文件在命令提示符窗口中进行了以下测试@echo %~dp0 executed. & exit /B 1

\n\n
start cmd.exe /K call Test.bat ^&^& exit\n
Run Code Online (Sandbox Code Playgroud)\n\n

Test.bat是一个批处理文件,而不是需要使用 command 的可执行文件call。没有特定窗口标题的启动命令进程保持打开状态,因为Test.bat退出时返回代码为 1。如果我将命令行的Test.bat\xc2\xa0end 处的数字 1 修改为 0,则启动的命令进程会自行退出。

\n\n

当然,使用此解决方案时,脚本代码本身有必要在脚本代码检测到错误时停止脚本执行。

\n