2012-11-15 80 views
16

所以我注意到它在等待命令完成之前繼續執行python腳本,我沒有辦法獲得標準輸出,除了subprocess.Popen。是否有任何其他函數調用會等到它完成? (我也試過Popen.waitPython subprocess.call和subprocess.Popen stdout

注:我試圖避免os.system呼叫

result = subprocess.Popen([commands..., 
         self.tmpfile.path()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = result.communicate() 
print out+"HIHIHI" 

我的輸出:

HIHIHI 

注意:我試圖運行wine與此有關。

+1

* subprocess.call()*可用於讀出/ err。 [請檢查手冊](http://docs.python.org/2/library/subprocess.html)。確保該命令不會產生大量輸出。 – tuxuday

回答

46

雖然您可能想要避免shell=True,但我正在使用以下構造。這給你的任何命令的輸出和錯誤信息,錯誤代碼以及:

process = subprocess.Popen(cmd, shell=True, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

# wait for the process to terminate 
out, err = process.communicate() 
errcode = process.returncode 
+0

我試過了,我仍然得到空的結果:s不完全確定我做錯了什麼。 –

+2

'cmd'的內容是什麼? – Alex

+0

@Alex cmd必須是您要執行的命令。 – NeoMorfeo

10

如果你的過程給出了一個巨大的stdout和無標準錯誤,communicate()可能是錯誤的路要走由於內存限制。

相反,

process = subprocess.Popen(cmd, shell=True, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

# wait for the process to terminate 
for line in process.stdout: do_something(line) 
errcode = process.returncode 

可能是要走的路。

process.stdout是一個類似文件的對象,你可以把任何其他這樣的對象,主要是:

  • 可以read()從中
  • 可以readline()從它和
  • 你可以遍歷它。

後者是我上面做的,以便逐行獲取其內容。

+1

你能向我解釋for循環的用途嗎? –

+0

@ Stupid.Fat.Cat它讀取由進程逐行生成的'stdout'並處理每一行。 – glglgl

+0

我得到'ValueError:在關閉文件上的I/O操作'爲'process.stdout中的行操作' – Yash89

11
subprocess.check_output(...) 

調用進程,如果其錯誤代碼爲非零則引發,否則返回其stdout。這只是一個快捷的速記,所以你不必擔心PIPE和事情。

+0

這有問題'酒'我相信。對不起,我會將其添加到我的問題中。 –

+3

這是一個很棒的功能,只是在Python 2.7或更新版本中。 – Gourneau

1

我想嘗試這樣的:

#!/usr/bin/python 
from __future__ import print_function 

import shlex 
from subprocess import Popen, PIPE 

def shlep(cmd): 
    '''shlex split and popen 
    ''' 
    parsed_cmd = shlex.split(cmd) 
    ## if parsed_cmd[0] not in approved_commands: 
    ## raise ValueError, "Bad User! No output for you!" 
    proc = Popen(parsed_command, stdout=PIPE, stderr=PIPE) 
    out, err = proc.communicate() 
    return (proc.returncode, out, err) 

...換句話說讓shlex.split()做的大部分工作。我不會嘗試解析shell的命令行,找到管道操作員並設置自己的管道。如果你打算這麼做,那麼你基本上必須編寫一個完整的shell語法分析器,最終你會做很多管道工作。

當然,這提出了一個問題,爲什麼不使用POPEN殼=真(關鍵字)選項?這可以讓你傳遞一個字符串(不分割也不解析)到shell中,並且仍然收集結果,以便隨意處理。我的例子在這裏不會處理可能在命令中的任何流水線,反引號,文件描述符重定向等,它們都將顯示爲命令的文字參數。因此,它仍然更安全,然後運行shell = True ...我已經給出了一個愚蠢的例子,檢查命令對某種「批准的命令」字典或設置 - 通過它會更有意義將其規範化爲絕對路徑,除非您打算要求參數在將命令字符串傳遞給此函數。

+0

我喜歡這個例子,提請注意shlex作爲解析命令行輸入的正確方法。幽默在這個例子中也是(shlep()和異常評論)。 :) –

相關問題