2010-12-11 123 views
6

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

这是我所用的初始代码:

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')。 这似乎解决了一个命令窗口的问题,但现在我不知道第一个程序何时完成,我可以开始第二个。在运行第二个程序之前,我想停止并询问第一个程序中的日志文件。

有关如何实现此目的的任何提示?是否有另一个选项可以在一个窗口中运行程序,我还没找到?

回答

6

由于您使用的是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 
+0

这将几乎工作。我基本上通过写入一个我自己打开的命令提示符来完成同样的事情。但问题是,在第一个命令完成后,我无法停止,检查日志文件,然后继续下一个命令。 – Sean 2010-12-11 20:25:41

+0

@Sean:看起来好像你可以使用一个允许你检查日志文件并确定批处理文件可以检查并用来确定是否退出或继续的退出代码来插入命令的调用。批处理程序支持'if [not] errorlevel ...'条件处理。如果你有兴趣,我可以更新我的答案,以显示如何做到这一点。 – martineau 2010-12-11 21:15:01

+0

谢谢马蒂诺。我对错误级别和批处理文件进行了快速搜索并找到它。谢谢您的帮助! – Sean 2010-12-12 16:55:05

0

在部分17.5.3.1。常量模块文档中有subprocess.CREATE_NEW_CONSOLE不变的description

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

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

的解决方案是有帮助脚本 - 姑且称之为发射 - 其中,默认情况下,创建控制台并运行你的程序的子进程。通过这种方式,每个程序都会从​​其父项中继承一个相同的控制台 - 启动器。要按顺序运行程序,我们使用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 
相关问题