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
-
终极实现方式
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