2010-12-11 115 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 
相關問題