【问题标题】:Run multiple programs sequentially in one Windows command prompt?在一个 Windows 命令提示符下按顺序运行多个程序?
【发布时间】:2011-05-23 20:13:11
【问题描述】:

我需要一个接一个地运行多个程序,每个程序都在控制台窗口中运行。 我希望控制台窗口可见,但会为每个程序创建一个新窗口。这很烦人,因为在 Eclipse 中工作时,每个窗口都在另一个窗口关闭的新位置打开并窃取焦点。

这是我使用的初始代码:

def runCommand( self, cmd, instream=None, outstream=None, errstream=None ):
    proc = subprocess.Popen( cmd, stdin=instream, stdout=outstream, stderr=errstream )

    while True:
        retcode = proc.poll()
        if retcode == None:
            if mAbortBuild:
                proc.terminate()
                return False
            else:
                time.sleep(1)
        else:
            if retcode == 0:
                return True
            else:
                return False

在调用 subprocess.Popen 然后调用 proc.stdin.write( b'program.exe\r\n' ) 时,我切换到使用 'cmd' 打开命令提示符。 这似乎解决了一个命令窗口问题,但现在我不知道第一个程序何时完成,我可以启动第二个程序。我想在运行第二个程序之前停止并询问第一个程序的日志文件。

关于如何实现这一点的任何提示?是否有其他选项可以在我尚未找到的窗口中运行程序?

【问题讨论】:

    标签: python windows eclipse console subprocess


    【解决方案1】:

    由于您使用的是 Windows,因此您可以创建一个批处理文件,列出您要运行的每个程序,这些程序都将在单个控制台窗口中执行。由于它是一个批处理脚本,因此您可以执行诸如在其中放入条件语句之类的操作,如示例所示。

    import os
    import subprocess
    import textwrap
    
    # create a batch file with some commands in it
    batch_filename = 'commands.bat'
    with open(batch_filename, "wt") as batchfile:
        batchfile.write(textwrap.dedent("""
            python hello.py
            if errorlevel 1 (
                @echo non-zero exit code: %errorlevel% - terminating
                exit
            )
            time /t
            date /t
        """))
    
    # execute the batch file as a separate process and echo its output
    kwargs = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                  universal_newlines=True)
    with subprocess.Popen(batch_filename, **kwargs).stdout as output:
        for line in output:
            print line,
    
    try: os.remove(batch_filename)  # clean up
    except os.error: pass
    

    【讨论】:

    • 这几乎可以工作。通过写入我自己打开的命令提示符,我基本上做了同样的事情。但问题是在第一个命令完成后我无法停止,检查日志文件,然后继续执行下一个命令。
    • @Sean:似乎您可以将命令的调用分散在允许您检查日志文件并确定退出代码的命令中,然后批处理文件可以检查并使用该代码来确定是否exit或继续。批处理程序支持if [not] errorlevel ... 条件处理。如果您有兴趣,我可以更新我的答案以说明如何做到这一点。
    • 谢谢马蒂诺。我对错误级别和批处理文件进行了快速搜索并找到了它。感谢您的帮助!
    • @Sean:好吧,我继续更新我的答案,以供其他可能感兴趣的人使用。
    • 您是否观察到问题中描述的行为 - 使用 Popen 时每个进程打开新控制台?我没有,这符合以下声明subprocess.CREATE_NEW_CONSOLE - The new process has a new console, instead of inheriting its parent’s console (the default).
    【解决方案2】:

    17.5.3.1 节中。 subprocess 模块文档中的常量 中有descriptionsubprocess.CREATE_NEW_CONSOLE 常量:

    新进程有一个新的控制台,而不是继承其父进程的 控制台(默认)。

    正如我们所见,默认情况下,新进程会继承其父进程的控制台。您观察到多个控制台被打开的原因是您从 Eclipse 中调用脚本,Eclipse 本身没有控制台,因此每个子进程都会创建自己的控制台,因为它没有可以继承的控制台。如果有人想模拟这种行为,运行 Python 脚本就足够了,该脚本使用 pythonw.exe 而不是 python.exe 创建子进程。两者的区别在于前者不打开控制台,而后者打开。

    解决方案是使用辅助脚本——我们称之为 launcher——默认情况下,它会创建控制台并在子进程中运行您的程序。这样,每个程序都从其父程序(launcher)继承了一个相同的控制台。要按顺序运行程序,我们使用Popen.wait() 方法。

    --- script_run_from_eclipse.py ---

    import subprocess
    import sys
    
    subprocess.Popen([sys.executable, 'helper.py'])
    

    --- helper.py ---

    import subprocess
    
    programs = ['first_program.exe', 'second_program.exe']
    for program in programs:
        subprocess.Popen([program]).wait()
        if input('Do you want to continue? (y/n): ').upper() == 'N':
            break
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 2011-12-08
      • 2012-08-11
      • 2013-06-17
      • 2010-11-23
      相关资源
      最近更新 更多