让我们首先分析一下两个发布的 Python 脚本行在执行 Python 脚本时的实际作用。感谢 eryksun 他对真正使用 Python 的深入调查得出了正确的描述,现在可以在下面阅读。
os.system() 导致在前台使用控制台窗口执行 cmd.exe /C 并暂停 Python 脚本的执行,直到 Windows 命令解释器终止。如果 Python 脚本本身在控制台中执行,则启动的 cmd.exe 会继承此控制台。
这个命令进程以start 开始,这是一个cmd.exe 的内部命令,还有一个带有前台控制台窗口的命令进程。很好,但是第二个命令进程在完成命令执行后立即终止。如果您想查看执行的脚本或 Python 解释器本身在运行 Python 脚本时输出的错误,那就不太好。
所以第二个命令进程以/k 选项启动cmd.exe 以继续运行此命令进程,继承start 创建的控制台,并在完成指定命令执行后打开控制台窗口。
第二个命令进程运行内部命令call,这根本没有必要,因为python 是真正的python.exe,一个控制台应用程序而不是一个批处理文件。因此,call 根本不需要。
建议始终使用完整的文件名指定应用程序和脚本,即文件名 + 文件扩展名,而不仅仅是文件名。如果可执行文件/脚本的路径已知且固定,则也应指定它。这使得应用程序/脚本的执行独立于当前目录和环境变量PATHEXT 和PATH。
Python 解释器在第二个控制台中执行指定的 Python 脚本。
以os.system() 开始的第一个命令进程在start 完成后立即终止,这在cmd.exe /k 开始后已经发生,而python.exe 正在解释Python 脚本。
剩下的就是运行 Python 解释器和脚本的第二个命令进程。即使 Python 解释器在完成指定 Python 脚本的执行后终止,此命令进程也会继续运行。
因此,目标是在 Python 解释器完成 Python 脚本的执行后也使用控制台窗口终止第二个命令进程,但前提是在执行脚本时没有发生错误。
好吧,我根本没有安装 Python,但我想它会在执行脚本时出现错误并以大于 0 的返回码退出。否则脚本成功执行时退出码为 0。
所以使用这样的命令可能会起作用:
command = 'start cmd.exe /K python.exe %s ^&^& exit' % (some_py_prog)
os.system(command)
以start cmd.exe /K 开头的第二个命令进程执行的命令行现在包含两个命令:
- Python 解释器
python.exe 将脚本作为参数执行
和
- 内部命令
exit,只有当第一个命令的退出代码是0,因为操作员&&,才应该由Windows命令解释器执行第二个命令。
请参阅Single line with multiple commands using Windows batch file 上的答案,了解有关要执行多个命令的单个命令行的详细信息。
每个&符号必须在此处使用 Windows 命令解释器的转义字符进行转义,即插入符号 ^。这是必要的,否则&& 将被运行start 的第一个命令进程解释为在成功执行start 后运行的附加命令。
请注意,我没有安装 Python,因此仅在命令提示符窗口中使用批处理文件 Test.bat 和单个命令行 @echo %~dp0 executed. & exit /B 1 进行了以下测试。
start cmd.exe /K call Test.bat ^&^& exit
Test.bat 是一个批处理文件,而不是需要使用命令call 的可执行文件。没有特定窗口标题的已启动命令进程保持打开状态,因为Test.bat 退出并返回代码 1。如果我在 Test.bat 中修改命令行末尾的数字 1 到 0,启动的命令进程将自行退出。
当然,在使用此解决方案时脚本代码检测到错误时,脚本代码本身需要暂停脚本执行。