国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

解決python subprocess參數(shù)shell=True踩到的坑

瀏覽:37日期:2022-06-21 15:03:33
0x01 問(wèn)題現(xiàn)象

寫(xiě)的程序使用subprocess創(chuàng)建子進(jìn)程運(yùn)行其他程序,判斷其他程序運(yùn)行完后進(jìn)行處理。

在subprocess使用了shell=True,判斷用戶(hù)程序退出的代碼如下

while self.proc.poll() is None: do_something

判斷子進(jìn)程是否運(yùn)行結(jié)束,程序在子進(jìn)程運(yùn)行結(jié)束后,代碼未向下繼續(xù)運(yùn)行,而是卡在了這個(gè)循環(huán)中。

0x02 原因分析

百度后對(duì)shell參數(shù)的解釋如下:

shell=True參數(shù)會(huì)讓subprocess.Popen接受字符串類(lèi)型的變量作為命令,并調(diào)用shell去執(zhí)行這個(gè)字符串,當(dāng)shell=False是,subprocess.Popen只接受數(shù)組變量作為命令,并將數(shù)組的第一個(gè)元素作為命令,剩下的全部作為該命令的參數(shù)。

通過(guò)查看服務(wù)器進(jìn)程可以看到,仍然有進(jìn)程存在,進(jìn)程如下

解決python subprocess參數(shù)shell=True踩到的坑

為shell中運(yùn)行的程序,由此可以得出,shell=true時(shí),子進(jìn)程在運(yùn)行完后,shell并沒(méi)有退出,而是卡在shell命令中,可由進(jìn)程看到。

解決python subprocess參數(shù)shell=True踩到的坑

補(bǔ)充:Python踩坑之旅其一殺不死的Shell子進(jìn)程

1.1 踩坑案例

踩坑的程序是個(gè)常駐的Agent類(lèi)管理進(jìn)程, 包括但不限于如下類(lèi)型的任務(wù)在執(zhí)行:

a. 多線(xiàn)程的網(wǎng)絡(luò)通信包處理

和控制Master節(jié)點(diǎn)交互

有固定Listen端口

b. 定期作業(yè)任務(wù), 通過(guò)subprocess.Pipe執(zhí)行shell命令

c. etc

發(fā)現(xiàn)坑的過(guò)程很有意思:

a.重啟Agent發(fā)現(xiàn)Port被占用了

=> 立刻想到可能進(jìn)程沒(méi)被殺死, 是不是停止腳本出問(wèn)題

=> 排除發(fā)現(xiàn)不是, Agent進(jìn)程確實(shí)死亡了

=> 通過(guò) netstat -tanop|grep port_number 發(fā)現(xiàn)端口確實(shí)有人占用

=> 調(diào)試環(huán)境, 直接殺掉占用進(jìn)程了之, 錯(cuò)失首次發(fā)現(xiàn)問(wèn)題的機(jī)會(huì)

b.問(wèn)題在一段時(shí)間后重現(xiàn), 重啟后Port還是被占用

定位問(wèn)題出現(xiàn)在一個(gè)叫做xxxxxx.sh的腳本, 該腳本占用了Agent使用的端口

=> 奇了怪了, 一個(gè)xxx.sh腳本使用這個(gè)奇葩Port干啥(大于60000的Port, 有興趣的磚友可以想下為什么Agent默認(rèn)使用6W+的端口)

=> review該腳本并沒(méi)有進(jìn)行端口監(jiān)聽(tīng)的代碼

一拍腦袋, c.進(jìn)程共享了父進(jìn)程資源了

=> 溯源該腳本,發(fā)現(xiàn)確實(shí)是Agent啟動(dòng)的任務(wù)中的腳本之一

=> 問(wèn)題基本定位, 該腳本屬于Agent調(diào)用的腳本

=> 該Agent繼承了Agent原來(lái)的資源FD, 也就是這個(gè)port

=> 雖然該腳本由于超時(shí)被動(dòng)觸發(fā)了terminate機(jī)制, 但terminate并沒(méi)有干掉這個(gè)子進(jìn)程

=> 該腳本進(jìn)程的父進(jìn)程(ppid) 被重置為了1

d.問(wèn)題****出在腳本進(jìn)程超時(shí)kill邏輯

1.2 填坑解法

通過(guò)代碼review, 找到shell具體執(zhí)行的庫(kù)代碼如下:

self._subpro = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=_signal_handle)# 重點(diǎn)是shell=True !

把上述代碼改為:

self._subpro = subprocess.Popen( cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=_signal_handle)# 重點(diǎn)是去掉了shell=True1.3 坑位分析

Agent會(huì)在一個(gè)新創(chuàng)建的threading線(xiàn)程中執(zhí)行這段代碼, 如果線(xiàn)程執(zhí)行時(shí)間超時(shí)(xx seconds), 會(huì)調(diào)用 self._subpro.terminate()終止該腳本.

表面正常:

啟用新線(xiàn)程執(zhí)行該腳本

如果出現(xiàn)問(wèn)題,執(zhí)行超時(shí)防止hang住其他任務(wù)執(zhí)行調(diào)用terminate殺死進(jìn)程

深層問(wèn)題:

Python 2.7.x中subprocess.Pipe 如果shell=True, 會(huì)默認(rèn)把相關(guān)的pid設(shè)置為shell(sh/bash/etc)本身(執(zhí)行命令的shell父進(jìn)程), 并非執(zhí)行cmd任務(wù)的那個(gè)進(jìn)程

子進(jìn)程由于會(huì)復(fù)制父進(jìn)程的opened FD表, 導(dǎo)致即使被殺死, 依然保留了擁有這個(gè)Listened Port FD

這樣雖然殺死了shell進(jìn)程(未必死亡, 可能進(jìn)入defunct狀態(tài)), 但實(shí)際的執(zhí)行進(jìn)程確活著. 于是1.1中的坑就被結(jié)實(shí)的踩上了.

1.4 坑后擴(kuò)展1.4.1 擴(kuò)展知識(shí)

本節(jié)擴(kuò)展知識(shí)包括二個(gè)部分:

Linux系統(tǒng)中, 子進(jìn)程一般會(huì)繼承父進(jìn)程的哪些信息

Agent這種常駐進(jìn)程選擇>60000端口的意義

擴(kuò)展知識(shí)留到下篇末尾講述, 感興趣的可以自行搜索

1.4.1 技術(shù)關(guān)鍵字

Linux系統(tǒng)進(jìn)程

Linux隨機(jī)端口選擇

程序多線(xiàn)程執(zhí)行

Shell執(zhí)行

1.5 填坑總結(jié)

1.子進(jìn)程會(huì)繼承父進(jìn)程的資源信息

2.如果只kill某進(jìn)程的父進(jìn)程, 集成了父進(jìn)程資源的子進(jìn)程會(huì)繼續(xù)占用父進(jìn)程的資源不釋放, 包括但不限于

listened port

opened fd

etc

3.Python Popen使用上, shell的bool狀態(tài)決定了進(jìn)程kill的邏輯, 需要根據(jù)場(chǎng)景選擇使用方式

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 欧美日韩一区二区三区视视频 | 欧美成人做性视频在线播放 | 亚洲在线观看免费 | 日本s色大片在线观看 | 欧美怡红院免费全视频 | 女人aaaaa片一级一毛片 | 日韩国产欧美一区二区三区 | 久久国产精品99久久小说 | 手机看片神马午夜 | 国产欧美在线观看视频 | 久揄揄鲁一二三四区高清在线 | 午夜日韩| 国产一级特黄一级毛片 | 中文字幕一区二区小泽玛利亚 | 精品成人在线 | 国产精品视频一区二区猎奇 | 一级欧美激情毛片 | 成人性动漫高清免费观看网址 | 九九99精品 | 久久视屏这里只有精品6国产 | 日本一级毛片免费 | 在线视频欧美日韩 | 美女张腿男人桶免费视频 | 免费观看亚洲视频 | 日本激情视频在线观看 | 欧美日韩精品乱国产538 | 国产欧美一区视频在线观看 | 免费v片在线观看 | 一级特黄aaa大片免费看 | 女同日韩互慰互摸在线观看 | 欧美成人免费观看国产 | 俄罗斯美女在线观看一区 | 久久亚洲国产最新网站 | 国产精品精品国产一区二区 | 亚洲成a人片在线观看 欧美 | 在线a人片免费观看国产 | 国产高清天干天天视频 | 91精品成人福利在线播放 | 男人的天堂网在线 | 欧美精品另类 | 亚洲精品亚洲人成毛片不卡 |