2012-12-20 86 views
3

我正在通過Python的子進程模塊運行命令行實用程序。我使用命令行參數和stdout = subprocess.PIPE創建了一個subprocess.Popen()對象,然後使用subprocess.wait()等待任務完成並返回應該指示任務是否成功完成的返回碼。即使發生錯誤,Python subprocess.Popen.wait()也會返回0

translate = subprocess.Popen(['gdal_translate', '-of', 'HFA', 'inDataset', 'outDataset'], stdout=subprocess.PIPE) 
if translate.wait() == 0: print "Success" 
else: print "Fail - %s" % translate.stdout.read() 

如果我跑我在Windows腳本命令提示符我可以看到gdal_translate提供的消息,他們說,有跡象表明導致進程失敗的錯誤,但我的腳本仍然打印「成功」。

如果返回碼始終爲0,如何檢查命令行實用程序報告的錯誤?

+1

如果直接在終端上運行的命令,什麼是它的退出代碼? – Useless

+0

如何查看終端中的退出代碼?這是我收到的錯誤消息的一個例子:'ERROR 1:path \ to \ dataset,band 1:IReadBlock failed in X offset 100,Y offset 331' – Brian

+1

在Windows上? 'echo%errorlevel%',我想。在bash中它會是'echo $?'。 – Useless

回答

3

您可能會得到錯誤輸出並仍然有返回碼爲零。在你的代碼中,你只能捕獲標準輸出而不是標準錯誤。在下面的運行函數中,它將運行一個命令,等待執行結束,然後讀取返回碼標準錯誤和標準輸出。如果有任何標準錯誤,或者如果返回碼不爲零,那麼它將視爲失敗。您可以在代碼中看到四個示例調用。第一個是正常的成功調用,第二個返回代碼0,但輸出錯誤和標準輸出。第三個具有非零返回碼和錯誤輸出,而最後一個例子具有非零返回碼,根本沒有輸出。

代碼

from subprocess import Popen, PIPE 

def run(cmd): 
    print '-'*40 
    print 'running:', cmd 
    p = Popen(cmd, stderr=PIPE, stdout=PIPE, shell=True) 
    output, errors = p.communicate() 
    print [p.returncode, errors, output] 
    if p.returncode or errors: 
     print 'something went wrong...' 

run("echo all is well") 
run("echo out;echo error 1>&2") 
run("this-will-fail") 
run("exit 1") 

輸出

---------------------------------------- 
running: echo all is well 
[0, '', 'all is well\n'] 
---------------------------------------- 
running: echo out;echo error 1>&2 
[0, 'error\n', 'out\n'] 
something went wrong... 
---------------------------------------- 
running: this-will-fail 
[127, '/bin/sh: this-will-fail: not found\n', ''] 
something went wrong... 
---------------------------------------- 
running: exit 1 
[1, '', ''] 
something went wrong... 
+0

如果程序產生足夠的輸出來填充管道緩衝區,則您提供的代碼可能會阻塞。你應該使用'subprocess.communicate'來代替:http://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate –

+0

@EdwardLoper我已經更新了使用溝通的答案,感謝評論。 –

相關問題