Subprocess管道卡死问题

<center><font face="黑体" bgcolor=#7FFFD4 size=5>Subprocess管道卡死</font></center>

  • 进程实现方法
import subprocess                                                                
import threading                                                                 
import time                                                                      
                                                                                    
                                                                                    
class TimeoutError(Exception):                                                      
    pass                                                                            
                                                                                    
class SubProcess(threading.Thread):                                                 
                                                                                    
    def __init__(self, cmd, timeout=None):                                       
                                                                                    
        super(SubProcess,self).__init__()                                           
                                                                                    
        self.cmd = cmd                                                              
        self.event = threading.Event()                                              
        self.stdout = ""                                                            
        self.stderr = ""                                                            
        self.retcode = None                                                         
        self.timeout = timeout                                                      
                                                                                    
                                                                                    
    def run(self):                                                                  
        try:                                                                        
            start_time = time.time()                                                
            read_flag = end_flag = False                                            
            PIPE = subprocess.PIPE                                                  
            sub = subprocess.Popen(self.cmd, shell=True, stderr=PIPE, stdout=PIPE)
                                                                                    
            while not self.event.is_set():                                          
                                                                                    
                end_time = time.time()                                              
                if self.timeout and (end_time-start()) >= self.timeout: 
                    self.retcode = -1                                            
                    self.stderr = "TimeOut"                                      
                    sub.terminate()                                              
                    break                                                        
                if not self.retcode == None and read_flag:                       
                    break                                                        
                                                                                 
                if not read_flag:                                                
                    line = sub.stdout.readline()                                 
                    if line:                                                     
                        self.stdout += line                                      
                    else:                                                        
                        read_flag = True                                         
                                                                                 
                if self.retcode ==  None:                                        
                    self.retcode = sub.poll()                                    
                                                                                 
        except Exception, ex:                                                    
            self.retcode = -1                                                    
            self.stderr = ex                                                     
                                                                                 
    def stop(self):                                                              
        self.event.set()                                                         
                                                                                 
sub = SubProcess("ls -l /root/")                                                 
                                                                                 
sub.start()                                                                      
sub.join()                                                                       
print repr(sub.stdout)                                                           
#print sub.stderr                                                                
print sub.retcode
  • 函数实现方法
def exec_command_ex(cmd, timeout=0):                                             
    stdout = stderr = ""                                                         
    start = time.time()                                                          
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,                
                         close_fds=True, stderr=subprocess.PIPE)                 
    while p.poll() is None:                                                      
        now = time.time()                                                        
        if timeout > 0 and (now - start) > timeout:                                 
            try:                                                                    
                p.terminate()                                                       
            except Exception as e:                                                  
                return -1, None, None                                               
                                                                                    
        stdout += sub.stdout.read()                                                 
        stderr += sub.stderr.read()                                                 
        time.sleep(0.1)                                                             
    if p:                                                                           
        ret = p.returncode                                                          
        if p.stdin:                                                                 
            p.stdin.close()                                                         
        if p.stdout:                                                                
            p.stdout.close()                                                        
        if p.stderr:                                                                
            p.stderr.close()                                                        
        try:                                                                     
            p.kill()                                                                
        except OSError:                                                             
            pass                                                                    
        return ret, stdout, stderr                                                  
    else:                                                                           
        return -1, None, None
  • 终极实现方式

    import subprocess
    import threading
    import time
    
    
    class TimeoutError(Exception):
        pass
    
    class SubProcess(threading.Thread):
    
        def __init__(self, cmd, timeout=None):
    
            super(SubProcess,self).__init__()
    
            self.cmd = cmd
            self.event = threading.Event()
            self.stdout = ""
            self.stderr = ""
            self.retcode = None
            self.timeout = timeout
    
    
        def run(self):
            try:
                start_time = time.time()
                read_flag = end_flag = False
                PIPE = subprocess.PIPE
                sub = subprocess.Popen(self.cmd, shell=True, stderr=PIPE, stdout=PIPE)
    
                while not self.event.is_set() and sub.poll() is None:
    
                   self.stdout += sub.stdout.read()
    
                   time.sleep(0.05)
    
                self.stderr +=sub.stderr.read()
                self.retcode = sub.returncode
                
                        except Exception, ex:
                self.retcode = -1
                self.stderr = ex
    
        def stop(self):
            self.event.set()
    
    def exec_command_ex(cmd, timeout=30):
        myout = ""
        myerror = ""
    
        start_time = end_time = time.time()
        #import pdb;pdb.set_trace()
        sub = SubProcess(cmd,5)
        sub.start()
    
        while True:
    
            if (end_time - start_time) > timeout:
                sub.stop()
                sub._Thread__stop()
                sub.retcode = 124
                sub.stderr = TimeoutError
                break
    
            if not sub.is_alive():
                break
    
            time.sleep(0.1)
            end_time = time.time()
    
        return sub.retcode,sub.stdout,sub.stderr
    
    #cmd = "cat /var/log/message"
    cmd = "sleep 10000"
    #cmd = "ls| grep 111"
    retcode,stdout,stderr =  exec_command_ex(cmd,5)
    print retcode,stderr
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,525评论 0 5
  • 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。进程的概念起源于操作系统,是操作系统最核心的概...
    SlashBoyMr_wang阅读 1,122评论 0 2
  • 最近在项目中遇到一个需求,前端发来一个命令,这个命令是去执行传递过来的一个脚本(shell 或者python),并...
    llicety阅读 49,978评论 8 19
  • ###总结得很不错!!### Python标准库06 子进程 (subprocess包) 作者:Vamei 出处:...
    Shirley_奋进中的虾米阅读 1,184评论 0 5
  • 什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单...
    可笑的黑耀斑阅读 995评论 0 0