python執(zhí)行shell命令行

概述

python中一般推薦的執(zhí)行shell命令行的方式有兩種毅人,os.popen與subprocess.Popen话瞧。本文(python 3.7環(huán)境)說(shuō)明下兩者的使用舷手,關(guān)聯(lián)與差異眉尸。

os.popen

os.popen的函數(shù)簽名比較簡(jiǎn)單:

def popen(cmd, mode="r", buffering=-1):

其中?cmd?必須為 string 類型秒紧,mode只能為 r?或者 w栗恩,buffering參數(shù)與內(nèi)建函數(shù) open?一致透乾,就不敘述了。

其返回值為 stdin?或者 stdout的wrapper磕秤,wrapper中實(shí)現(xiàn)了迭代特性乳乌,因此可以使用像普通文件對(duì)象一樣遍歷內(nèi)容。

import os

dirs = os.popen('dir')

[dir for dir in dirs]

從參數(shù)上看市咆,popen只支持單工通信(read mode?或 write mode)汉操。

從內(nèi)部實(shí)現(xiàn)上來(lái)說(shuō),os.popen內(nèi)部調(diào)用了?subprocess.Popen函數(shù)蒙兰,調(diào)用如下:

if mode == "r":

????proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=buffering)

????return _wrap_close(io.TextIOWrapper(proc.stdout), proc)

else:

????proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, bufsize=buffering)

????return _wrap_close(io.TextIOWrapper(proc.stdin), proc)

關(guān)于?subprocess.Popen?中的?shell 參數(shù)與 stdin/stdout參數(shù)我們會(huì)在后面分析磷瘤。

subprocess.Popen

Popen是一個(gè)類,并不是一個(gè)函數(shù)搜变。內(nèi)部實(shí)現(xiàn)比較復(fù)雜采缚,隔離了操作系統(tǒng)的差異。

def __init__(self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None):

其構(gòu)造函數(shù)相當(dāng)復(fù)雜痹雅,我們逐步進(jìn)行解析仰担。

這些參數(shù)中,部分分屬不同的操作系統(tǒng)绩社,Popen會(huì)做簡(jiǎn)單檢查后再進(jìn)行下一步處理摔蓝。

posix:preexec_fn

windows:startupinfo,createionflag

這些參數(shù)如果熟悉windows與Liunx創(chuàng)建進(jìn)程的API愉耙,應(yīng)該不會(huì)有什么疑問(wèn)贮尉,具體可以查看?MSDN?與?man?手冊(cè)。

args就是我們的命令行參數(shù)了朴沿,args可以是一個(gè)string猜谚,也可以是一個(gè)list败砂。如果是一個(gè)srting的話,Popen內(nèi)部會(huì)將其轉(zhuǎn)換成 list魏铅。

bufsize?與 os.popen的 buffering參數(shù)含義相同

executable?參數(shù)指的是需要運(yùn)行的可執(zhí)行文件昌犹,如果?這個(gè)參數(shù)不等于None,那么 args就作為參數(shù)傳遞給executable所指向的可執(zhí)行文件览芳。executable會(huì)受到shell參數(shù)的影響斜姥,后續(xù)我們會(huì)分析到。

stdin/stdout/strerr?主要用于輸入輸出的重定向功能沧竟。實(shí)參可以是?PIPE/DEVNULL/文件描述符/文件對(duì)象/None铸敏。

熟悉linux編程的朋友應(yīng)該都知道PIPE與devnull。如果輸入PIPE悟泵,那么Popen會(huì)在父進(jìn)程與子進(jìn)程之間創(chuàng)建輸入輸出的pipe用于相互通信杈笔。

如果實(shí)參是已經(jīng)打開的?文件描述符或文件對(duì)象時(shí),那么輸入輸出就會(huì)重定向到相應(yīng)的文件中糕非。

如果實(shí)參等于?None蒙具,那么直接使用?標(biāo)準(zhǔn)輸入輸出接口。

注意?bufsize?參數(shù)是針對(duì) stdin/stdout/stderr?的緩沖設(shè)置峰弹。

preexec_fn?參數(shù)只有在 posix環(huán)境中才有用店量。在?child_exec?執(zhí)行到?exec*?函數(shù)前會(huì)執(zhí)行?result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);?作用顯而易見芜果,在child exec之前設(shè)置一個(gè)回調(diào)函數(shù)鞠呈,在這個(gè)特殊的時(shí)機(jī)做一些特殊的操作。

close_fds?這個(gè)參數(shù)感覺在posix環(huán)境中更有意義一些右钾,如果設(shè)置為True蚁吝,相當(dāng)于為0,1舀射,2以外的文件設(shè)置了?CLOSEXEC?標(biāo)志窘茁。在windows中則將默認(rèn)的文件繼承屬性設(shè)置為FALSE。

pass_fds 用于在父子進(jìn)程間傳遞文件句柄脆烟。在posix中山林,如果pass_fds不為None,那么close_fds必須為True邢羔。也就是說(shuō)pass_fds中的句柄會(huì)被關(guān)掉驼抹。

查看源碼的時(shí)候發(fā)現(xiàn)比較奇怪的地方,在posix中拜鹤,pass_fds?設(shè)置完繼承屬性后框冀,如果close_fds為True,那么所有的句柄都會(huì)被關(guān)掉敏簿,那么pass_fds還能正常繼承到子進(jìn)程中嗎明也?這里需要測(cè)試一下宣虾。

cwd是個(gè)人所共知的參數(shù),不細(xì)說(shuō)温数。只是要注意 cwd?會(huì)影響py腳本的查找與執(zhí)行绣硝。

restore_signals參數(shù)也是在posix中作用比較大,因?yàn)閣indows中信號(hào)功能實(shí)在太弱撑刺。具體功能就是將 SIGPIPE/SIGXFZ/SIGXFSZ?由SIG_IGN設(shè)置成?SIG_DFL域那。具體可以參考任意的linux參考書。

start_new_session?應(yīng)該只能在posix中使用猜煮,如果設(shè)置為True次员,那么子進(jìn)程在執(zhí)行過(guò)程中會(huì)調(diào)用 setsid,開啟一個(gè)新的會(huì)話王带。

env簡(jiǎn)單淑蔚,忽略不講。

encoding/errors/universal_newline/text都是與 stdin/stdout/stderr相關(guān)的參數(shù)愕撰。

結(jié)語(yǔ)

os.popen的參數(shù)簡(jiǎn)單刹衫,使用方便;subprocess.Popen參數(shù)復(fù)雜搞挣,能實(shí)現(xiàn)精細(xì)控制带迟。并且os.popen只能用于單工環(huán)境,即重定向stdin或者stdout文件囱桨,但是subprocess.Popen可以實(shí)現(xiàn) 0/1/2?三個(gè)描述符同時(shí)重定向仓犬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舍肠,隨后出現(xiàn)的幾起案子搀继,更是在濱河造成了極大的恐慌,老刑警劉巖翠语,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叽躯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肌括,警方通過(guò)查閱死者的電腦和手機(jī)点骑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谍夭,“玉大人黑滴,你說(shuō)我怎么就攤上這事』劭猓” “怎么了跷跪?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)齐板。 經(jīng)常有香客問(wèn)我吵瞻,道長(zhǎng)葛菇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上鲫构,老公的妹妹穿的比我還像新娘。我一直安慰自己莺债,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布签夭。 她就那樣靜靜地躺著齐邦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪第租。 梳的紋絲不亂的頭發(fā)上措拇,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音慎宾,去河邊找鬼丐吓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趟据,可吹牛的內(nèi)容都是我干的券犁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汹碱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼粘衬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起比被,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤色难,失蹤者是張志新(化名)和其女友劉穎泼舱,沒想到半個(gè)月后等缀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娇昙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年尺迂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冒掌。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡噪裕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出股毫,到底是詐尸還是另有隱情膳音,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布铃诬,位于F島的核電站祭陷,受9級(jí)特大地震影響苍凛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兵志,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一醇蝴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧想罕,春花似錦悠栓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至楼镐,卻和暖如春腥沽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸠蚪。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工今阳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茅信。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓盾舌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蘸鲸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子妖谴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 處于學(xué)習(xí)別人代碼風(fēng)格階段,github參考學(xué)習(xí)程序程序開頭會(huì)有 一是用來(lái)指定腳本語(yǔ)言為 Python酌摇,二是用來(lái)指定...
    lifesmily閱讀 1,055評(píng)論 0 0
  • 1.os.system('cmd') os.system('cat /proc/cpuinfo') 直接執(zhí)行參數(shù)中...
    奇_66a0閱讀 14,142評(píng)論 0 5
  • 工作中出于對(duì)一個(gè)腳本的優(yōu)化膝舅,需要使用Python執(zhí)行外部命令。這篇文章也算是工作的簡(jiǎn)單總結(jié)窑多。執(zhí)行外部命令有多種方法...
    我叫GTD閱讀 2,485評(píng)論 0 0
  • 深夜厭倦
    小小風(fēng)車閱讀 184評(píng)論 0 0
  • 我常常需要和我的失落感做斗爭(zhēng)仍稀,它總是猝不及防且無(wú)法壓制。 老實(shí)說(shuō)我并不喜歡這種感覺埂息,總與挫敗技潘,難堪,軟弱某些失意的...
    藍(lán)藍(lán)藍(lán)莓醬閱讀 323評(píng)論 0 1