Using module 'subprocess' with timeout

后端 未结 29 2821
旧巷少年郎
旧巷少年郎 2020-11-21 15:15

Here\'s the Python code to run an arbitrary command returning its stdout data, or raise an exception on non-zero exit codes:

proc = subprocess.P         


        
29条回答
  •  我在风中等你
    2020-11-21 16:06

    import subprocess, optparse, os, sys, re, datetime, threading, time, glob, shutil, xml.dom.minidom, traceback
    
    class OutputManager:
        def __init__(self, filename, mode, console, logonly):
            self.con = console
            self.logtoconsole = True
            self.logtofile = False
    
            if filename:
                try:
                    self.f = open(filename, mode)
                    self.logtofile = True
                    if logonly == True:
                        self.logtoconsole = False
                except IOError:
                    print (sys.exc_value)
                    print ("Switching to console only output...\n")
                    self.logtofile = False
                    self.logtoconsole = True
    
        def write(self, data):
            if self.logtoconsole == True:
                self.con.write(data)
            if self.logtofile == True:
                self.f.write(data)
            sys.stdout.flush()
    
    def getTimeString():
            return time.strftime("%Y-%m-%d", time.gmtime())
    
    def runCommand(command):
        '''
        Execute a command in new thread and return the
        stdout and stderr content of it.
        '''
        try:
            Output = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]
        except Exception as e:
            print ("runCommand failed :%s" % (command))
            print (str(e))
            sys.stdout.flush()
            return None
        return Output
    
    def GetOs():
        Os = ""
        if sys.platform.startswith('win32'):
            Os = "win"
        elif sys.platform.startswith('linux'):
            Os = "linux"
        elif sys.platform.startswith('darwin'):
            Os = "mac"
        return Os
    
    
    def check_output(*popenargs, **kwargs):
        try:
            if 'stdout' in kwargs: 
                raise ValueError('stdout argument not allowed, it will be overridden.') 
    
            # Get start time.
            startTime = datetime.datetime.now()
            timeoutValue=3600
    
            cmd = popenargs[0]
    
            if sys.platform.startswith('win32'):
                process = subprocess.Popen( cmd, stdout=subprocess.PIPE, shell=True) 
            elif sys.platform.startswith('linux'):
                process = subprocess.Popen( cmd , stdout=subprocess.PIPE, shell=True ) 
            elif sys.platform.startswith('darwin'):
                process = subprocess.Popen( cmd , stdout=subprocess.PIPE, shell=True ) 
    
            stdoutdata, stderrdata = process.communicate( timeout = timeoutValue )
            retcode = process.poll()
    
            ####################################
            # Catch crash error and log it.
            ####################################
            OutputHandle = None
            try:
                if retcode >= 1:
                    OutputHandle = OutputManager( 'CrashJob_' + getTimeString() + '.txt', 'a+', sys.stdout, False)
                    OutputHandle.write( cmd )
                    print (stdoutdata)
                    print (stderrdata)
                    sys.stdout.flush()
            except Exception as e:
                print (str(e))
    
        except subprocess.TimeoutExpired:
                ####################################
                # Catch time out error and log it.
                ####################################
                Os = GetOs()
                if Os == 'win':
                    killCmd = "taskkill /FI \"IMAGENAME eq {0}\" /T /F"
                elif Os == 'linux':
                    killCmd = "pkill {0)"
                elif Os == 'mac':
                    # Linux, Mac OS
                    killCmd = "killall -KILL {0}"
    
                runCommand(killCmd.format("java"))
                runCommand(killCmd.format("YouApp"))
    
                OutputHandle = None
                try:
                    OutputHandle = OutputManager( 'KillJob_' + getTimeString() + '.txt', 'a+', sys.stdout, False)
                    OutputHandle.write( cmd )
                except Exception as e:
                    print (str(e))
        except Exception as e:
                for frame in traceback.extract_tb(sys.exc_info()[2]):
                            fname,lineno,fn,text = frame
                            print "Error in %s on line %d" % (fname, lineno)
    

提交回复
热议问题