天天看點

python commands.getoutput_Python3中用什麼替換commands子產品的getstatusoutput()

先翻譯一段文章: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(). 謝謝這位朋友。

(完)