Python 從subprocess運(yùn)行的子進(jìn)程中實(shí)時(shí)獲取輸出的例子
有些時(shí)候,我們需要將某些程序放到子進(jìn)程中去運(yùn)行,以達(dá)到整合系統(tǒng)的目的。在Python中,一個(gè)非常好的選擇就是使用subprocess模塊,本模塊為開辟子進(jìn)程去執(zhí)行子程序提供了統(tǒng)一的接口,更加便于學(xué)習(xí)和使用。
同時(shí),對(duì)于在子進(jìn)程里的程序,我們希望能夠?qū)崟r(shí)獲取其輸出,以在主進(jìn)程中打印相關(guān)信息,使我們能夠了解當(dāng)前子程序的執(zhí)行進(jìn)度。對(duì)此,subprocess模塊也提供了相應(yīng)的參數(shù),能夠?qū)⒆映绦虻臉?biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出返回給主程序。
下面,我們就通過一個(gè)例子來說明這個(gè)功能。首先,我們需要一個(gè)用于模擬標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出的“子程序”——subprogram.py:
import sys
import time
for i in range(5):
sys.stdout.write('Processing {}\n'.format(i))
time.sleep(1)
for i in range(5):
sys.stderr.write('Error {}\n'.format(i))
time.sleep(1)
可以看到這個(gè)程序非常簡(jiǎn)單,分別向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤寫入了5條信息,并且輸出之間有1秒的間隔。下面是驅(qū)動(dòng)這個(gè)“子程序”運(yùn)行的“主程序”——main.py:
import shlex
import subprocess
if __name__ == '__main__':
shell_cmd = 'python3 subprogram.py'
cmd = shlex.split(shell_cmd)
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while p.poll() is None:
line = p.stdout.readline()
line = line.strip()
if line:
print('Subprogram output: [{}]'.format(line))
if p.returncode == 0:
print('Subprogram success')
else:
print('Subprogram failed')
可以看到,我們通過指定stderr=subprocess.STDOUT,將子程序的標(biāo)準(zhǔn)錯(cuò)誤輸出重定向到了標(biāo)準(zhǔn)輸出,以使我們可以直接從標(biāo)準(zhǔn)輸出中同時(shí)獲取標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤的信息。運(yùn)行這個(gè)程序,我們會(huì)期待main.py會(huì)每秒輸出一次信息到控制臺(tái),但是事實(shí)上,我們直到等了10秒之后才一次性看到所有的10條輸出。
產(chǎn)生這種現(xiàn)象的原因也非常簡(jiǎn)單,就是標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤有一個(gè)緩存的概念,它不會(huì)立即將程序的標(biāo)準(zhǔn)輸出內(nèi)容返回,而是會(huì)做一定的緩存,直到緩存滿或者程序結(jié)束強(qiáng)制清空緩存時(shí)才輸出。了解到問題的原因,解決問題的方法也就一目了然了,我們只需要在子程序中,每次輸出后去手動(dòng)清空一下緩存即可,以下是修改過的subprogram.py:
import sys
import time
for i in range(5):
sys.stdout.write('Processing {}\n'.format(i))
sys.stdout.flush()
time.sleep(1)
for i in range(5):
sys.stderr.write('Error {}\n'.format(i))
sys.stderr.flush()
time.sleep(1)
經(jīng)過上述的修改之后,再次運(yùn)行main.py程序,我們會(huì)看到,每秒會(huì)輸出一條信息,達(dá)到了我們?cè)谥鞒绦蛑校プ粉欁映绦驁?zhí)行過程的目的。
PS:測(cè)試環(huán)境是Python3.6.1 Mac版。
以上這篇Python 從subprocess運(yùn)行的子進(jìn)程中實(shí)時(shí)獲取輸出的例子就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
django restframework使用redis實(shí)現(xiàn)token認(rèn)證
本文主要介紹了django restframework使用redis實(shí)現(xiàn)token認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
python pandas 對(duì)series和dataframe的重置索引reindex方法
今天小編就為大家分享一篇python pandas 對(duì)series和dataframe的重置索引reindex方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06
python創(chuàng)建文件時(shí)去掉非法字符的方法
今天小編就為大家分享一篇python創(chuàng)建文件時(shí)去掉非法字符的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10
python獲取list下標(biāo)及其值的簡(jiǎn)單方法
下面小編就為大家?guī)硪黄猵ython獲取list下標(biāo)及其值的簡(jiǎn)單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09
淺析python 內(nèi)置字符串處理函數(shù)的使用方法
這篇文章主要介紹了python 內(nèi)置字符串處理函數(shù)的使用方法,需要的朋友可以參考下2014-06-06
Python2.7環(huán)境Flask框架安裝簡(jiǎn)明教程【已測(cè)試】
這篇文章主要介紹了Python2.7環(huán)境Flask框架安裝方法,結(jié)合實(shí)例形式詳細(xì)分析了Python2.7環(huán)境下安裝Flask框架遇到的問題與相關(guān)解決方法、注意事項(xiàng),并給出了一個(gè)基本的測(cè)試示例,需要的朋友可以參考下2018-07-07

