先翻譯一段文章:https://stackoverflow.com/questions/11344557/replacement-for-getstatusoutput-in-python-3
在最後的“注意”一節中,給出筆者自己的看法。
在Python 2中,經常使用commands子產品來執行shell的指令,尤其是常用getstatusoutput()函數。但是在Python 3中,突然發現這個函數沒有了。為什麼呢?
因為getstatusoutput()這個函數有一個很大的缺陷,就是它的傳回值中無法區分stderr和stdout.
那麼在Python 3中如果要調用一個指令,如何做呢?有2種方法。其實它們在Python 2中也适用。
方法1. 使用subprocess.check_output()函數
如果指令調用失敗,check_output()會抛出一個CalledProcessError的異常。
如果要看到stderr的内容,即合并stdout和stderr,可以把 stderr=subprocess.STDOUT 作為check_output的一個參數。
方法2. 自己定制一個get_status_output()函數,内容如下:
def get_status_output(*args, **kwargs):
p = subprocess.Popen(*args, **kwargs)
stdout, stderr = p.communicate()
return p.returncode, stdout, stderr
注意:
1. 在調用check_output()或定制化的get_status_output()的時候,“ls -l”這樣的指令要寫成“ls -l”.split(' '), 即把指令和參數等作為一個數組輸入,而并非一個字元串。
2. 筆者做了一些測試:
方法1無論在Python 2還是Python 3中皆是可行,但要注意,在Python 3中傳回的output是bytes,不是str類型;
方法2無論在Python 2還是Python 3中皆是失敗的:stdout和stderr始終為None,雖然指令确實被執行了并且也有傳回,但是stdout和stderr卻拿不到傳回。
但是如果使用方法1,就必須去捕捉異常,否則無法處理指令執行失敗的情況。
相比之下,又有多少人會去在意stdout和stderr呢?大概會有一些特殊的情況需要處理stdout和stderr的區分吧。
是以,回過頭來,感覺Python2的commands.getstatusoutput()其實是一個很友善的函數,寫起來很快,1行就結束了。
最後,有朋友(dawn_Eve)在本文評論中指出了Python 3中的commands.getstatusoutput()的替代方案,即 subprocess.getstatusoutput(). 謝謝這位朋友。
(完)