<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