python 中Subprocess如何使用,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)建站始終堅(jiān)持【策劃先行,效果至上】的經(jīng)營(yíng)理念,通過多達(dá)10余年累計(jì)超上千家客戶的網(wǎng)站建設(shè)總結(jié)了一套系統(tǒng)有效的全網(wǎng)推廣解決方案,現(xiàn)已廣泛運(yùn)用于各行各業(yè)的客戶,其中包括:成都航空箱等企業(yè),備受客戶贊美。
一、subprocess以及常用的封裝函數(shù), 連接文檔,Popen不用wait用communicate
運(yùn)行python的時(shí)候,我們都是在創(chuàng)建并運(yùn)行一個(gè)進(jìn)程。像Linux進(jìn)程那樣,一個(gè)進(jìn)程可以fork一個(gè)子進(jìn)程,并讓這個(gè)子進(jìn)程exec另外一個(gè)程序。在Python中,我們通過標(biāo)準(zhǔn)庫(kù)中的subprocess包來fork一個(gè)子進(jìn)程,并運(yùn)行一個(gè)外部的程序。
subprocess包中定義有數(shù)個(gè)創(chuàng)建子進(jìn)程的函數(shù),這些函數(shù)分別以不同的方式創(chuàng)建子進(jìn)程,所以我們可以根據(jù)需要來從中選取一個(gè)使用。另外subprocess還提供了一些管理標(biāo)準(zhǔn)流(standard stream)和管道(pipe)的工具,從而在進(jìn)程間使用文本通信。
subprocess模塊是python從2.4版本開始引入的模塊。主要用來取代一些舊的模塊方法,如os.system、os.spawn*、os.popen*、commands.*等。subprocess通過子進(jìn)程來執(zhí)行外部指令,并通過input/output/error管道,獲取子進(jìn)程的執(zhí)行的返回信息。
調(diào)用subprocess的推薦方法是對(duì)于它可以處理的所有使用場(chǎng)景都使用run()函數(shù)。run()函數(shù)是在Python 3.5中添加的,如果在老版本中使用,需要下載并擴(kuò)展。
pip install subprocess.run
使用方法
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False,env=None)
運(yùn)行args描述的命令。等待命令完成,然后返回一個(gè)CompletedProcess實(shí)例。class subprocess.CompletedProcess表示從run()返回的值,表示已完成的進(jìn)程。
完整的函數(shù)形式很大程度上與Popen構(gòu)造函數(shù)相同 —— 除timeout、input和check之外,該函數(shù)的所有參數(shù)都傳遞給Popen接口。
args是所有調(diào)用所必需的,應(yīng)該為一個(gè)字符串或一個(gè)程序參數(shù)序列l(wèi)ist。通常傾向提供參數(shù)序列,因?yàn)樗试S這個(gè)模塊來處理任何所需的轉(zhuǎn)義和引用參數(shù)(例如,允許文件名中的空格)。如果傳遞單個(gè)字符串,shell必須為True(見下文),否則字符串必須簡(jiǎn)單地命名要執(zhí)行的程序而不指定任何參數(shù)。
stdin、stdout和stderr分別指定執(zhí)行程序的標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤文件句柄。有效值有PIPE、DEVNULL,一個(gè)存在的文件描述器(正整數(shù)),一個(gè)存在的文件對(duì)象和None。PIPE表示應(yīng)該為子進(jìn)程創(chuàng)建新的管道。DEVNULL表示將使用特殊文件os.devnull。使用默認(rèn)設(shè)置None,則不會(huì)發(fā)生重定向;子進(jìn)程的文件句柄將從父進(jìn)程繼承。此外,stderr可以是STDOUT,表示來自子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤數(shù)據(jù)應(yīng)該捕獲到與stdout相同的文件句柄中。
如果shell是True,則將通過shell執(zhí)行指定的命令。如果你使用Python主要是由于它能提供大多數(shù)系統(tǒng)shell不能提供的增強(qiáng)的控制流,并且仍然希望方便地訪問其他shell功能,如shell管道、文件名通配符、環(huán)境變量擴(kuò)展和擴(kuò)展?到用戶的主目錄,這會(huì)很有用。
>>> from subprocess import run
>>> print run('uname -r')
3.7.0-7-generic
>>> print run('uname -r').stdout
3.7.0-7-generic
>>> run('uname -a').status
0
>>> print run('rm not_existing_directory').stderr
rm: cannot remove `not_existing_directory': No such file or directory
>>> print run('ls -la', 'wc -l')
14
>>> print run('ls -la', 'wc -l', 'wc -c')
3
>>> run('ls -la', 'wc -l', 'wc -c')
ls -la | wc -l | wc -c
>>> print run('ls -la').stdout.lines
['total 20',
'drwxrwxr-x 3 user user 4096 Dec 20 22:55 .',
'drwxrwxr-x 5 user user 4096 Dec 20 22:57 ..',
'drwxrwxr-x 2 user user 4096 Dec 20 22:37 dir',
'-rw-rw-r-- 1 user user 0 Dec 20 22:52 file']只是執(zhí)行一些指令的時(shí)候通過subprocess.run 即可。可以指定stdout,stderr,cwd(代碼工作路徑),env(環(huán)境變量)
def get_path_env(kaldi=DIR.KALDI): # 在kaldi內(nèi)部 注意添加環(huán)境變量
old_path = os.environ['PATH']
ivectorbin_dir = os.path.join(kaldi, 'src', 'ivectorbin')
bin_dir = os.path.join(kaldi, 'src', 'bin')
new_path = "{}:{}:{}".format(ivectorbin_dir, bin_dir, old_path)
return {"PATH": new_path}env = get_path_env() ,env = {'PATH':$PATH} 這種形式。
有時(shí)候需要將一個(gè)進(jìn)程的輸入當(dāng)做另外一個(gè)進(jìn)程的輸出,用到subprocess.Popen
import subprocess child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE) child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE) out = child2.communicate()
def transform(xvector_scp_fp, test_scp_fp, test_ark_fp, sre16_major_dir=None, sre_combined_dir=None):
"""
Transform xvector from dimension of 600 to vecotr of dimension 150.
The actual dimensions are decided by `transform.mat`.
Params:
`sre16_major_dir`: The official `xvectors_sre16_major` directory, which contains `mean.vec`;
`sre_combined_dir`: The official `xvectors_sre_combined` directory, which contains `transform.mat`;
`xvector_scp_fp`: scp file path for xvectors to be transformed;
`test_scp_fp`: location of the destination file path
NOTE: Here we generate scp file and ark file, instead of only ark file. The reason is to accommandate
the case where a lot of xvectors are invloved. Since xvector scp file is
created by default, we don't have to consider when there is not xvector scp file.
"""
sre16_major_dir = sre16_major_dir or path.join(DIR.CONSTDIR, 'xvectors_sre16_major')
sre_combined_dir = sre_combined_dir or path.join(DIR.CONSTDIR, 'xvectors_sre_combined')
env = get_path_env() # 執(zhí)行路徑對(duì)應(yīng)第69行,run_faiss.sh
subtract_cmd = ['ivector-subtract-global-mean']
mean_vec_dir = path.join(sre16_major_dir, 'mean.vec')
subtract_cmd.append(mean_vec_dir)
subtract_cmd.append("scp:{}".format(xvector_scp_fp))
subtract_cmd.append("ark:-")
p1 = subprocess.Popen(subtract_cmd, stdout=subprocess.PIPE, env=env, stderr=subprocess.DEVNULL) # p1.stdout
trans_cmd = ['transform-vec']
trans_mat_fp = path.join(sre_combined_dir, 'transform.mat')
trans_cmd.append(trans_mat_fp)
trans_cmd.append("ark:-")
trans_cmd.append("ark:-")
p2 = subprocess.Popen(trans_cmd, stdin=p1.stdout, stdout=subprocess.PIPE, env=env, stderr=subprocess.DEVNULL)
norm_cmd = ['ivector-normalize-length']
norm_cmd.append('ark:-')
dest = "ark,scp:{},{}".format(test_ark_fp, test_scp_fp)
norm_cmd.append(dest)
p3 = subprocess.Popen(norm_cmd, stdin=p2.stdout, stdout=subprocess.PIPE, env=env,stderr=subprocess.PIPE)
# wait for p3 to execute
rv = p3.communicate()[0]
if p3.returncode != 0:
raise XvectorTransformationError(p3.stdout, p3.stderr)p3.communicate()
p3.returncode != 0
rv.returncode != 0
class PldaScoreError(Exception):
"""plda score error"""
def cmd_err(err_cls): # 添加報(bào)警錯(cuò)誤,plda_scores_error
def outer(fn):
def inner(*args, **kwargs):
rv = fn(*args, **kwargs)
if rv.returncode != 0:
err_msg = rv.stdout + rv.stderr # 報(bào)警錯(cuò)誤信息顯示,
if type(err_msg) is bytes:
err_msg = err_msg.decode()
print(err_msg)
raise err_cls
else:
return rv
return inner
return outer
@cmd_err(PldaScoreError)
def score(enroll_ark_fp, test_ark_fp, trials_fp, score_fp, log_dir=None, sre16_major_dir=default_sre16, cwd=DIR.KALDIROOT): # 不需要 num_utts.ark 文件
"""
Params:
`sre16_major_dir`: the directory where `plda_adapt` locates
`enroll_ark_fp`: enroll ark file path
`test_ark_fp`: test ark file path
`trials_fp`: trials file path
`score_fp`: the file path for the generated score file
"""
log_dir = log_dir or (score_fp + ".log")
cmd = ['utils/run.pl']
cmd.append(log_dir)
cmd.append("ivector-plda-scoring")
cmd.append("--normalize-length=true")
plda_fp = path.join(sre16_major_dir, 'plda_adapt')
plda_sub_cmd = "ivector-copy-plda --smoothing=0.0 {} - |".format(plda_fp)
cmd.append(plda_sub_cmd)
cmd.append("ark:{}".format(enroll_ark_fp))
cmd.append("ark:{}".format(test_ark_fp))
cmd.append(trials_fp)
cmd.append(score_fp)
env = get_path_env()
return subprocess.run(cmd, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # cwd 設(shè)定子進(jìn)程當(dāng)前工作目錄,env 用于指定子進(jìn)程環(huán)境變量,env關(guān)于python 中Subprocess如何使用問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
名稱欄目:python中Subprocess如何使用
網(wǎng)頁(yè)鏈接:http://chinadenli.net/article0/jiegio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、軟件開發(fā)、微信小程序、自適應(yīng)網(wǎng)站、網(wǎng)站內(nèi)鏈、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)