Subprocess管道卡死问题

2020-03-20  本文已影响0人  _艾_斯_

<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
上一篇下一篇

猜你喜欢

热点阅读