避免python Popen阻塞__python

來源:互聯網
上載者:User

http://backend.blog.163.com/blog/static/2022941262014016710912/


很多開發和營運人員喜歡用python做一些開發或是營運的工作。不可避免要調用系統命令。
調用系統命令的方式有兩種,一種是os.system(CMD),一種是subprocess.Popen(CMD,stdout=what,stderr=what)。
如: import os os.system("echo hi")
或者 import subprocess obj=subprocess.Popen("echo hi")
但是這通常不能滿足要求。我們一般需要解析執行命令之後的輸出,並從輸出中解析出我們想要的資訊。
前一種無法滿足要求,os.system無法有效輸出cmd執行之後的結果。只能使用subprocess的方式。
通常的做法如下:


import subprocess import traceback
try:     cmd = "ls -lh"     obj = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)     obj.wait()          lines = obj.stdout.readlines()          if not lines or len(lines) == 0:         line = obj.stderr.readlines()          print lines except Exception, e:     print traceback.format_exc()

這樣做在大多數情況下都不會有問題。但是這裡影藏了潛在的危險。就是會發現有一天程式hang住了。 這可能導致整個應用被掛住。當你費了很大力氣定位問題時,會發現罪魁禍首便是Popen。而令人困惑的 是,這個地方你已經測試過n次了。怎麼會在這裡hang住了呢。
原因是subprocess的PIPE是有大小的。在python2.6.11之前,PIPE的大小為檔案頁的大小(i386上是4096), 2.6.11之後變為65536.因此當輸出內容超過65536,會引起阻塞。因為PIPE已經被塞滿了,無法再塞進更多的 資料。
解決方案是不用subprocess提供的PIPE,而是使用自己建立的流。如此,可以控制流程的大小。不多說,直接 上代碼: import subprocess import traceback import tempfile try:     cmd = "ls -lh"     out_temp = tempfile.SpooledTemporaryFile(bufsize=10*1000)     fileno = out_temp.fileno()     obj = subprocess.Popen(cmd,stdout=fileno,stderr=fileno,shell=True)     obj.wait()          out_temp.seek(0)     lines = out_temp.readlines()               print lines except Exception, e:     print traceback.format_exc() finally:     if out_temp:         out_temp.close()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.