python调用linux命令输出结果,Python-运行shell命令并捕获输出
小編典典
這個(gè)問(wèn)題的答案取決于你使用的Python版本。最簡(jiǎn)單的方法是使用以下subprocess.check_output功能:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
該check_output功能適用于仍在廣泛使用的幾乎所有版本的Python(2.7+)。2但對(duì)于較新的版本,不再推薦使用此方法。
現(xiàn)代版本的Python(3.5或更高版本): run
如果你使用的是Python 3.5或更高版本,并且不需要向后兼容,則建議使用新run功能。它為該subprocess模塊提供了非常通用的高級(jí)API 。要捕獲程序的輸出,請(qǐng)將subprocess.PIPE標(biāo)志傳遞給stdout關(guān)鍵字參數(shù)。然后訪問(wèn)stdout返回CompletedProcess對(duì)象的屬性:
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
返回值是一個(gè)bytes對(duì)象,因此,如果你需要正確的字符串,則需要decode它。假設(shè)被調(diào)用的進(jìn)程返回一個(gè)UTF-8編碼的字符串:
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
所有這些都可以壓縮為一種格式:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
如果要將輸入傳遞給流程的stdin,bytes請(qǐng)將一個(gè)對(duì)象傳遞給input關(guān)鍵字參數(shù):
>>> cmd = ['awk', 'length($0) > 5']
>>> input = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)
>>> result.stdout.decode('utf-8')
'foofoo\n'
你可以通過(guò)傳遞stderr=subprocess.PIPE(捕獲到result.stderr)或stderr=subprocess.STDOUT(捕獲到result.stdout常規(guī)輸出)來(lái)捕獲錯(cuò)誤。如果不考慮安全性,你還可以shell=True按照下面的說(shuō)明通過(guò)傳遞來(lái)運(yùn)行更復(fù)雜的Shell命令。
與舊的工作方式相比,這僅增加了一點(diǎn)復(fù)雜性。但是我認(rèn)為值得這樣做:現(xiàn)在,你僅需使用該run功能就可以完成幾乎所有需要做的事情。
舊版本的Python(2.7-3.4): check_output
如果你使用的是舊版本的Python,或者需要適度的向后兼容性,則可以使用check_output上面簡(jiǎn)要介紹的函數(shù)。自python 2.7開(kāi)始可用。
subprocess.check_output(*popenargs, **kwargs)
它采用與Popen(請(qǐng)參見(jiàn)下文)相同的參數(shù),并返回一個(gè)包含程序輸出的字符串。該答案的開(kāi)頭有一個(gè)更詳細(xì)的用法示例。在Python 3.5及更高版本中,check_output等效于run使用check=True和stdout=PIPE,僅返回stdout屬性。
你可以通過(guò)stderr=subprocess.STDOUT確保錯(cuò)誤信息包含在返回的輸出-但在Python中通過(guò)一些版本stderr=subprocess.PIPE,以check_output可引起死鎖。如果不考慮安全性,你還可以shell=True按照下面的說(shuō)明通過(guò)傳遞來(lái)運(yùn)行更復(fù)雜的Shell命令。
如果你需要通過(guò)管道stderr傳遞輸入或?qū)⑤斎雮鬟f給流程,check_output則將無(wú)法完成任務(wù)。Popen在這種情況下,請(qǐng)參見(jiàn)下面的示例。
復(fù)雜的應(yīng)用程序和Python的舊版(2.6及以下版本): Popen
如果需要深度向后的兼容性,或者需要比check_output提供的功能更復(fù)雜的功能,則必須直接使用Popen對(duì)象,這些對(duì)象封裝了用于子流程的低級(jí)API。
所述Popen構(gòu)造器接受單個(gè)命令沒(méi)有參數(shù),或列表包含指令作為其第一項(xiàng),其次是任意數(shù)量的參數(shù),每個(gè)作為列表一個(gè)單獨(dú)的項(xiàng)目。shlex.split可以幫助將字符串解析為格式正確的列表。Popen對(duì)象還接受用于進(jìn)程IO管理和低級(jí)配置的許多不同參數(shù)。
發(fā)送輸入和捕獲輸出communicate幾乎始終是首選方法。如:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
要么
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
如果設(shè)置stdin=PIPE,communicate還允許你通過(guò)以下方式將數(shù)據(jù)傳遞到流程stdin:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
注艾倫·霍爾的回答,這表明在某些系統(tǒng)上,你可能需要設(shè)置stdout,stderr以及stdin所有PIPE(或DEVNULL)得到communicate工作的。
在極少數(shù)情況下,你可能需要復(fù)雜的實(shí)時(shí)輸出捕獲。Vartec的答案提出了一條前進(jìn)的道路,但是communicate如果不謹(jǐn)慎使用,則其他方法都容易出現(xiàn)死鎖。
與上述所有功能一樣,當(dāng)不考慮安全性時(shí),可以通過(guò)傳遞運(yùn)行更復(fù)雜的Shell命令shell=True。
筆記
1.運(yùn)行shell命令:shell=True參數(shù)
通常,對(duì)run,check_output或Popen構(gòu)造函數(shù)的每次調(diào)用都會(huì)執(zhí)行一個(gè)程序。這意味著沒(méi)有花哨的bash風(fēng)格的管道。如果要運(yùn)行復(fù)雜的Shell命令,則可以傳遞shell=True,這三個(gè)功能都支持。
但是,這樣做會(huì)引起安全問(wèn)題。如果你要做的不僅僅是輕腳本編寫(xiě),那么最好單獨(dú)調(diào)用每個(gè)進(jìn)程,并將每個(gè)進(jìn)程的輸出作為輸入通過(guò)以下方式傳遞給下一個(gè)進(jìn)程:
run(cmd, [stdout=etc...], input=other_output)
要么
Popen(cmd, [stdout=etc...]).communicate(other_output)
直接連接管道的誘惑力很強(qiáng);抵抗它。否則,你可能會(huì)遇到僵局,或者不得不做類(lèi)似此類(lèi)的駭人聽(tīng)聞的事情。
2. Unicode注意事項(xiàng)
check_output在Python 2中返回一個(gè)字符串,但bytes在Python 3中返回一個(gè)對(duì)象。如果還沒(méi)有,則花一點(diǎn)時(shí)間來(lái)學(xué)習(xí)unicode。
2020-02-06
總結(jié)
以上是生活随笔為你收集整理的python调用linux命令输出结果,Python-运行shell命令并捕获输出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 平行世界是什么意思 平行世界解释
- 下一篇: linux useradd 数字,详解l