【问题标题】:keep multiple console windows open from batch从批处理中保持多个控制台窗口打开
【发布时间】:2012-08-20 19:02:16
【问题描述】:

如何让批处理文件按顺序执行多个 (Python) 脚本,每个脚本都在各自的窗口中,并在完成后保持所有这些窗口打开?现在,我的批次是这样的:

python script1
start python script2
pause/cmd

但只有父窗口保持打开状态。

谢谢。

环境: Windows XP/Vista

【问题讨论】:

  • 有很多方法可以做到这一点。首先要问一些问题:让您的原始脚本在这段时间内保持活跃是否可以?您是否可以假设您对目录具有写访问权限,例如%TEMP% 目录还是包含原始脚本的目录?让您的原始脚本执行“睡眠”可执行文件并轮询 python 脚本的完成是否可以?大概你想执行多少个python脚本,即有一个巨大的长命令行来执行它们是否合理,还是有太多?
  • 你需要将参数传递给你的脚本,还是你总是只用一个简单的“python [scriptFileName]”来执行它们?
  • 对第一条评论中的所有内容都同意。大约 4-8 个脚本可能是典型用法。我愿意使用一个巨大的命令行。没有传递参数。

标签: python windows batch-file cmd


【解决方案1】:

您可以使用start 命令打开一个新窗口(在后台使用/min)并运行命令

start "window1" /min cmd.exe /c "pause"

最后的命令,pause 可以是任何东西,只要确保全部用引号括起来

要保持窗口打开,您应该将内容放在批处理脚本中,并在最后一条语句中暂停

【讨论】:

  • 我试过了:start "window1" cmd.exe /c "python script1.py & pause" start "window2" cmd.exe /c "python script2.py & pause" 但这会导致 同时 执行,而不是想要的顺序执行。我也尝试使用 /wait 选项,但是第一个脚本中的“暂停”命令会阻止批处理文件继续执行下一个脚本。有没有办法让窗口保持打开而不停止批处理文件?
【解决方案2】:

如果您只有两个脚本,那么您的想法是正确的,只是语法错误:

start cmd.exe /k "python script1.py & start cmd.exe /k python script2.py"

如果您需要窗口标题:

start "Window1" cmd.exe /K "python script1.py & start "window2" cmd.exe /K python script2.py"

脚本多于两个,您将不得不求助于更复杂的东西。以下 .cmd 文件可以解决问题:

@echo off
if "%~1" == "recurse" goto runScript%~2

start "Window1" cmd /k "%~f0 recurse 1"
exit /b 0

:runScript1
python script1.py
start "Window2" cmd /k "%~f0 recurse 2"
exit /b 0

:runScript2
python script2.py
start "Window3" cmd /k "%~f0 recurse 3"
exit /b 0

:runScript3
python script3.py
exit /b 0

这可以扩展到任意数量的脚本或命令,脚本具有任意参数等。如果您希望 cmd 窗口只是暂停,并在您按下某个键时消失:

@echo off
if "%~1" == "recurse" goto runScript%~2

start "Window1" cmd /c "%~f0 recurse 1"
exit /b 0

:runScript1
python script1.py
start "Window2" cmd /c "%~f0 recurse 2"
pause
exit /b 0

:runScript2
python script2.py
start "Window3" cmd /c "%~f0 recurse 3"
pause
exit /b 0

:runScript3
python script3.py
pause
exit /b 0

如果您希望它们在最后一个窗口上按一个键立即终止:

@echo off
if "%~1" == "recurse" goto runScript%~2

start "Window1" cmd /c "%~f0 recurse 1"
exit /b 0

:runScript1
python script1.py
start "Window2" /wait cmd /c "%~f0 recurse 2"
exit /b 0

:runScript2
python script2.py
start "Window3" /wait cmd /c "%~f0 recurse 3"
exit /b 0

:runScript3
python script3.py
pause
exit /b 0

所以,对于脚本的行为,您有很多选择。

【讨论】:

  • 两个脚本选项效果很好。只是出于好奇,这是否可以嵌套在两个脚本之外,还是除了可读性之外还有一些障碍?明天我会尝试更通用的解决方案。谢谢!
  • 如果你能弄清楚引号的转义规则,你可以使用 Python 生成命令行:print reduce(lambda cmd, script: r'start cmd.exe /k "python %s & %s"' % (script, cmd), reversed("1.py 2.py 3.py 4.py".split()), "echo done")
  • cmd.exe 在解析和匹配引号方面做得很差,在解析和匹配括号方面做得更差。我无法让它执行 3 个脚本,因此使用了其他代码。
【解决方案3】:

[to] 在各自的窗口中按顺序执行多个 (Python) 脚本,并在完成时保持所有这些窗口打开

#!/usr/bin/env python
"""Continuation-passing style (CPS) script.

Usage:

   $ python cps.py script1.py arg1 arg2 -- script2.py a b c -- script3.py ...
"""
import platform
import sys
from subprocess import call

if len(sys.argv) < 2:
    sys.exit() # nothing to do

# define a command that starts new terminal
if platform.system() == "Windows":
    new_window_command = "cmd.exe /c start cmd.exe /c".split()
else:  #XXX this can be made more portable
    new_window_command = "x-terminal-emulator -e".split()

# find where script args end
end = sys.argv.index('--') if '--' in sys.argv else len(sys.argv)

# call script; wait while it ends; ignore errors
call([sys.executable] + sys.argv[1:end])

# start new window; call itself; pass the rest; ignore errors
rest = sys.argv[end+1:]
if rest:
    call(new_window_command + [sys.executable, sys.argv[0]] + rest)

print("Press Enter to exit") #NOTE: to avoid raw_input/input py3k shenanigans
sys.stdin.readline()

它支持在命令行上提供的尽可能多的脚本及其参数。

如果您不为脚本使用参数;你可以简化用法:

$ python cps.py script1.py script2.py script3.py

注意:脚本之间没有--。这种情况下需要修改代码:

  • 设置end = 2
  • rest = sys.argv[end:](注:没有+1

【讨论】:

  • 在 cmd 行中我输入了python cps.py script01.py -- script02.py(这三个脚本都与 python.exe 在同一个文件夹中)。这正确执行了 script01,但随后以 WindowsError: [Error 2] The system cannot find the file specified 停止。我还尝试将其他文件作为 script02.关于可能是什么问题的任何想法? Traceback 在下一条评论中:
  • 回溯是 `File "cpsScript.py",第 32 行,在 call(new_window_command + [sys.executable, sys.argv[0]] + rest) File "c:\Python27\lib\subprocess.py",第 493 行,调用中 return Popen(*popenargs, **kwargs).wait() File "c:\Python27\lib\subprocess.py",第 679 行,在 init_ errread, errwrite) File "c:\Python27\lib\subprocess.py",第 896 行,在 _execute_child 启动信息中)`
  • @beets: new_window_command 错了。我已经更新了答案
猜你喜欢
  • 2012-11-24
  • 2014-04-20
  • 2010-12-26
  • 2013-06-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多