首页 文章

使用模块'subprocess'超时

提问于
浏览
272

这是运行任意命令返回其 stdout 数据的Python代码,或者在非零退出代码上引发异常:

proc = subprocess.Popen(
    cmd,
    stderr=subprocess.STDOUT,  # Merge stdout and stderr
    stdout=subprocess.PIPE,
    shell=True)

communicate 用于等待进程退出:

stdoutdata, stderrdata = proc.communicate()

subprocess 模块不支持超时 - 能够终止运行超过X秒的进程 - 因此, communicate 可能需要永久运行 .

什么是在Python程序中实现超时的 simplest 方式,以便在Windows和Linux上运行?

29 回答

  • 78

    如果你在Unix上,

    import signal
      ...
    class Alarm(Exception):
        pass
    
    def alarm_handler(signum, frame):
        raise Alarm
    
    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(5*60)  # 5 minutes
    try:
        stdoutdata, stderrdata = proc.communicate()
        signal.alarm(0)  # reset the alarm
    except Alarm:
        print "Oops, taking too long!"
        # whatever else
    
  • 94

    在Python 3.3中:

    from subprocess import STDOUT, check_output
    
    output = check_output(cmd, stderr=STDOUT, timeout=seconds)
    

    output 是一个字节字符串,包含命令的合并stdout,stderr数据 .

    proc.communicate() 方法不同,此代码在问题文本中指定的非零退出状态上引发 CalledProcessError .

    我删除了 shell=True 因为它经常被不必要地使用 . 如果 cmd 确实需要它,您可以随时添加它 . 如果添加 shell=True ,即子进程生成自己的后代; check_output() 可以在超时指示的时间之后返回,请参阅Subprocess timeout failure .

    Python 2.x上的超时功能可通过3.2子进程模块的subprocess32 backport获得 .

  • 2

    我对低级细节知之甚少;但是,鉴于在python 2.6中,API提供了等待线程和终止进程的能力,那么在单独的线程中运行进程呢?

    import subprocess, threading
    
    class Command(object):
        def __init__(self, cmd):
            self.cmd = cmd
            self.process = None
    
        def run(self, timeout):
            def target():
                print 'Thread started'
                self.process = subprocess.Popen(self.cmd, shell=True)
                self.process.communicate()
                print 'Thread finished'
    
            thread = threading.Thread(target=target)
            thread.start()
    
            thread.join(timeout)
            if thread.is_alive():
                print 'Terminating process'
                self.process.terminate()
                thread.join()
            print self.process.returncode
    
    command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
    command.run(timeout=3)
    command.run(timeout=1)
    

    我机器中此代码段的输出是:

    Thread started
    Process started
    Process finished
    Thread finished
    0
    Thread started
    Process started
    Terminating process
    Thread finished
    -15
    

    可以看出,在第一次执行中,进程正确完成(返回代码0),而在第二次执行中进程终止(返回代码-15) .

    我没有在Windows中测试过;但是,除了更新示例命令之外,我认为它应该可以工作,因为我没有在文档中找到任何说明不支持thread.join或process.terminate的内容 .

  • 16

    使用threading.Timer类可以简化jcollado的答案:

    import shlex
    from subprocess import Popen, PIPE
    from threading import Timer
    
    def run(cmd, timeout_sec):
        proc = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
        timer = Timer(timeout_sec, proc.kill)
        try:
            timer.start()
            stdout, stderr = proc.communicate()
        finally:
            timer.cancel()
    
    # Examples: both take 1 second
    run("sleep 1", 5)  # process ends normally at 1 second
    run("sleep 5", 1)  # timeout happens at 1 second
    
  • 0

    Alex Martelli的解决方案是一个具有适当进程终止的模块 . 其他方法不起作用,因为它们不使用proc.communicate() . 因此,如果您有一个产生大量输出的进程,它将填充其输出缓冲区然后阻塞,直到您从中读取内容 .

    from os import kill
    from signal import alarm, signal, SIGALRM, SIGKILL
    from subprocess import PIPE, Popen
    
    def run(args, cwd = None, shell = False, kill_tree = True, timeout = -1, env = None):
        '''
        Run a command with a timeout after which it will be forcibly
        killed.
        '''
        class Alarm(Exception):
            pass
        def alarm_handler(signum, frame):
            raise Alarm
        p = Popen(args, shell = shell, cwd = cwd, stdout = PIPE, stderr = PIPE, env = env)
        if timeout != -1:
            signal(SIGALRM, alarm_handler)
            alarm(timeout)
        try:
            stdout, stderr = p.communicate()
            if timeout != -1:
                alarm(0)
        except Alarm:
            pids = [p.pid]
            if kill_tree:
                pids.extend(get_process_children(p.pid))
            for pid in pids:
                # process might have died before getting to this line
                # so wrap to avoid OSError: no such process
                try: 
                    kill(pid, SIGKILL)
                except OSError:
                    pass
            return -9, '', ''
        return p.returncode, stdout, stderr
    
    def get_process_children(pid):
        p = Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True,
                  stdout = PIPE, stderr = PIPE)
        stdout, stderr = p.communicate()
        return [int(p) for p in stdout.split()]
    
    if __name__ == '__main__':
        print run('find /', shell = True, timeout = 3)
        print run('find', shell = True)
    
  • 130

    我修改了 sussudio 回答 . 现在函数返回:( returncodestdoutstderrtimeout ) - stdoutstderr 被解码为utf-8字符串

    def kill_proc(proc, timeout):
      timeout["value"] = True
      proc.kill()
    
    def run(cmd, timeout_sec):
      proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      timeout = {"value": False}
      timer = Timer(timeout_sec, kill_proc, [proc, timeout])
      timer.start()
      stdout, stderr = proc.communicate()
      timer.cancel()
      return proc.returncode, stdout.decode("utf-8"), stderr.decode("utf-8"), timeout["value"]
    
  • 1

    惊讶没有提到使用 timeout

    timeout 5 ping -c 3 somehost

    这显然不适用于每个用例,但如果你处理一个简单的脚本,这很难被击败 .

    对于mac用户,也可以通过 homebrew 在coreutils中作为gtimeout使用 .

  • -1

    另一种选择是写入临时文件以防止stdout阻塞而不需要使用communic()进行轮询 . 这对我有用,而其他答案没有;例如在Windows上 .

    outFile =  tempfile.SpooledTemporaryFile() 
        errFile =   tempfile.SpooledTemporaryFile() 
        proc = subprocess.Popen(args, stderr=errFile, stdout=outFile, universal_newlines=False)
        wait_remaining_sec = timeout
    
        while proc.poll() is None and wait_remaining_sec > 0:
            time.sleep(1)
            wait_remaining_sec -= 1
    
        if wait_remaining_sec <= 0:
            killProc(proc.pid)
            raise ProcessIncompleteError(proc, timeout)
    
        # read temp streams from start
        outFile.seek(0);
        errFile.seek(0);
        out = outFile.read()
        err = errFile.read()
        outFile.close()
        errFile.close()
    
  • -2

    timeout is now supportedcall()communicate() 在子进程模块中(从Python3.3开始):

    import subprocess
    
    subprocess.call("command", timeout=20, shell=True)
    

    这将调用该命令并引发异常

    subprocess.TimeoutExpired
    

    如果命令在20秒后没有完成 .

    然后,您可以处理异常以继续您的代码,例如:

    try:
        subprocess.call("command", timeout=20, shell=True)
    except subprocess.TimeoutExpired:
        # insert code here
    

    希望这可以帮助 .

  • 5

    这是我的解决方案,我使用线程和事件:

    import subprocess
    from threading import Thread, Event
    
    def kill_on_timeout(done, timeout, proc):
        if not done.wait(timeout):
            proc.kill()
    
    def exec_command(command, timeout):
    
        done = Event()
        proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
        watcher = Thread(target=kill_on_timeout, args=(done, timeout, proc))
        watcher.daemon = True
        watcher.start()
    
        data, stderr = proc.communicate()
        done.set()
    
        return data, stderr, proc.returncode
    

    在行动:

    In [2]: exec_command(['sleep', '10'], 5)
    Out[2]: ('', '', -9)
    
    In [3]: exec_command(['sleep', '10'], 11)
    Out[3]: ('', '', 0)
    
  • 7

    我使用的解决方案是在shell命令前加上timelimit . 如果命令花费太长时间,则timelimit将停止它并且Popen将具有由timelimit设置的返回码 . 如果它> 128,则意味着timelimit杀死了该进程 .

    另见python subprocess with timeout and large output (>64K)

  • 15

    我添加了从 jcollado 到我的Python模块easyprocess的线程解决方案 .

    安装:

    pip install easyprocess
    

    例:

    from easyprocess import Proc
    
    # shell is not supported!
    stdout=Proc('ping localhost').call(timeout=1.5).stdout
    print stdout
    
  • 0

    如果您使用的是python 2,请尝试一下

    import subprocess32
    
    try:
        output = subprocess32.check_output(command, shell=True, timeout=3)
    except subprocess32.TimeoutExpired as e:
        print e
    
  • 4

    只是想写一些更简单的东西 .

    #!/usr/bin/python
    
    from subprocess import Popen, PIPE
    import datetime
    import time 
    
    popen = Popen(["/bin/sleep", "10"]);
    pid = popen.pid
    sttime = time.time();
    waittime =  3
    
    print "Start time %s"%(sttime)
    
    while True:
        popen.poll();
        time.sleep(1)
        rcode = popen.returncode
        now = time.time();
        if [ rcode is None ]  and  [ now > (sttime + waittime) ] :
            print "Killing it now"
            popen.kill()
    
  • 43

    我没有提及但是从Python 3.5开始,有一个新的subprocess.run通用命令(意味着要取代 check_callcheck_output ...),并且它也有 timeout 参数 .

    subprocess.run(args,*,stdin = None,input = None,stdout = None,stderr = None,shell = False,cwd = None,timeout = None,check = False,encoding = None,errors = None)

    Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.
    

    超时到期时,它会引发 subprocess.TimeoutExpired 异常 .

  • 3

    我已经实现了从其中一些我可以收集到的东西 . 这适用于Windows,因为这是一个社区维基,我想我也会分享我的代码:

    class Command(threading.Thread):
        def __init__(self, cmd, outFile, errFile, timeout):
            threading.Thread.__init__(self)
            self.cmd = cmd
            self.process = None
            self.outFile = outFile
            self.errFile = errFile
            self.timed_out = False
            self.timeout = timeout
    
        def run(self):
            self.process = subprocess.Popen(self.cmd, stdout = self.outFile, \
                stderr = self.errFile)
    
            while (self.process.poll() is None and self.timeout > 0):
                time.sleep(1)
                self.timeout -= 1
    
            if not self.timeout > 0:
                self.process.terminate()
                self.timed_out = True
            else:
                self.timed_out = False
    

    然后从另一个类或文件:

    outFile =  tempfile.SpooledTemporaryFile()
            errFile =   tempfile.SpooledTemporaryFile()
    
            executor = command.Command(c, outFile, errFile, timeout)
            executor.daemon = True
            executor.start()
    
            executor.join()
            if executor.timed_out:
                out = 'timed out'
            else:
                outFile.seek(0)
                errFile.seek(0)
                out = outFile.read()
                err = errFile.read()
    
            outFile.close()
            errFile.close()
    
  • 0

    一旦您了解* unix中的完整流程运行机器,您将很容易找到更简单的解决方案:

    考虑这个简单的例子如何使用select.select()进行超时的communic()方法(现在在* nix上几乎可以使用) . 这也可以用epoll / poll / kqueue编写,但select.select()变体可能是一个很好的例子 . select.select()(速度和1024最大fds)的主要限制不适用于您的任务 .

    这在* nix下工作,不创建线程,不使用信号,可以从任何线程(不仅是主线程)推出,并且快速从我的机器上的stdout读取250mb / s的数据(i5 2.3ghz) .

    在通信结束时加入stdout / stderr会出现问题 . 如果你有巨大的程序输出,这可能会导致大量的内存使用 . 但是你可以用较小的超时调用communic()几次 .

    class Popen(subprocess.Popen):
        def communicate(self, input=None, timeout=None):
            if timeout is None:
                return subprocess.Popen.communicate(self, input)
    
            if self.stdin:
                # Flush stdio buffer, this might block if user
                # has been writing to .stdin in an uncontrolled
                # fashion.
                self.stdin.flush()
                if not input:
                    self.stdin.close()
    
            read_set, write_set = [], []
            stdout = stderr = None
    
            if self.stdin and input:
                write_set.append(self.stdin)
            if self.stdout:
                read_set.append(self.stdout)
                stdout = []
            if self.stderr:
                read_set.append(self.stderr)
                stderr = []
    
            input_offset = 0
            deadline = time.time() + timeout
    
            while read_set or write_set:
                try:
                    rlist, wlist, xlist = select.select(read_set, write_set, [], max(0, deadline - time.time()))
                except select.error as ex:
                    if ex.args[0] == errno.EINTR:
                        continue
                    raise
    
                if not (rlist or wlist):
                    # Just break if timeout
                    # Since we do not close stdout/stderr/stdin, we can call
                    # communicate() several times reading data by smaller pieces.
                    break
    
                if self.stdin in wlist:
                    chunk = input[input_offset:input_offset + subprocess._PIPE_BUF]
                    try:
                        bytes_written = os.write(self.stdin.fileno(), chunk)
                    except OSError as ex:
                        if ex.errno == errno.EPIPE:
                            self.stdin.close()
                            write_set.remove(self.stdin)
                        else:
                            raise
                    else:
                        input_offset += bytes_written
                        if input_offset >= len(input):
                            self.stdin.close()
                            write_set.remove(self.stdin)
    
                # Read stdout / stderr by 1024 bytes
                for fn, tgt in (
                    (self.stdout, stdout),
                    (self.stderr, stderr),
                ):
                    if fn in rlist:
                        data = os.read(fn.fileno(), 1024)
                        if data == '':
                            fn.close()
                            read_set.remove(fn)
                        tgt.append(data)
    
            if stdout is not None:
                stdout = ''.join(stdout)
            if stderr is not None:
                stderr = ''.join(stderr)
    
            return (stdout, stderr)
    
  • 1

    你可以用 select 做到这一点

    import subprocess
    from datetime import datetime
    from select import select
    
    def call_with_timeout(cmd, timeout):
        started = datetime.now()
        sp = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        while True:
            p = select([sp.stdout], [], [], timeout)
            if p[0]:
                p[0][0].read()
            ret = sp.poll()
            if ret is not None:
                return ret
            if (datetime.now()-started).total_seconds() > timeout:
                sp.kill()
                return None
    
  • 2

    预装Linux命令 timeout 并不是一个糟糕的解决方法,它对我有用 .

    cmd = "timeout 20 "+ cmd
    subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (output, err) = p.communicate()
    
  • 10

    我在Windows,Linux和Mac上成功使用了killableprocess . 如果您使用Cygwin Python,则需要OSAF's version of killableprocess,否则本机Windows进程将不会被杀死 .

  • 1

    虽然我没有广泛地看过它,但我在ActiveState中发现这似乎对这类事情非常有用 . 与 subprocess.Popen(..., close_fds=True) 一起,至少我已经准备好在Python中使用shell脚本了 .

  • 189

    有一个想法是继承Popen类并使用一些简单的方法装饰器扩展它 . 我们称之为ExpirablePopen .

    from logging import error
    from subprocess import Popen
    from threading import Event
    from threading import Thread
    
    
    class ExpirablePopen(Popen):
    
        def __init__(self, *args, **kwargs):
            self.timeout = kwargs.pop('timeout', 0)
            self.timer = None
            self.done = Event()
    
            Popen.__init__(self, *args, **kwargs)
    
        def __tkill(self):
            timeout = self.timeout
            if not self.done.wait(timeout):
                error('Terminating process {} by timeout of {} secs.'.format(self.pid, timeout))
                self.kill()
    
        def expirable(func):
            def wrapper(self, *args, **kwargs):
                # zero timeout means call of parent method
                if self.timeout == 0:
                    return func(self, *args, **kwargs)
    
                # if timer is None, need to start it
                if self.timer is None:
                    self.timer = thr = Thread(target=self.__tkill)
                    thr.daemon = True
                    thr.start()
    
                result = func(self, *args, **kwargs)
                self.done.set()
    
                return result
            return wrapper
    
        wait = expirable(Popen.wait)
        communicate = expirable(Popen.communicate)
    
    
    if __name__ == '__main__':
        from subprocess import PIPE
    
        print ExpirablePopen('ssh -T git@bitbucket.org', stdout=PIPE, timeout=1).communicate()
    
  • 2

    我遇到的问题是,如果花费超过给定的超时长度,我想终止多线程子进程 . 我想在 Popen() 中设置超时,但它不起作用 . 然后,我意识到 Popen().wait() 等于 call() ,所以我有想法在 .wait(timeout=xxx) 方法中设置超时,最终有效 . 因此,我这样解决了:

    import os
    import sys
    import signal
    import subprocess
    from multiprocessing import Pool
    
    cores_for_parallelization = 4
    timeout_time = 15  # seconds
    
    def main():
        jobs = [...YOUR_JOB_LIST...]
        with Pool(cores_for_parallelization) as p:
            p.map(run_parallel_jobs, jobs)
    
    def run_parallel_jobs(args):
        # Define the arguments including the paths
        initial_terminal_command = 'C:\\Python34\\python.exe'  # Python executable
        function_to_start = 'C:\\temp\\xyz.py'  # The multithreading script
        final_list = [initial_terminal_command, function_to_start]
        final_list.extend(args)
    
        # Start the subprocess and determine the process PID
        subp = subprocess.Popen(final_list)  # starts the process
        pid = subp.pid
    
        # Wait until the return code returns from the function by considering the timeout. 
        # If not, terminate the process.
        try:
            returncode = subp.wait(timeout=timeout_time)  # should be zero if accomplished
        except subprocess.TimeoutExpired:
            # Distinguish between Linux and Windows and terminate the process if 
            # the timeout has been expired
            if sys.platform == 'linux2':
                os.kill(pid, signal.SIGTERM)
            elif sys.platform == 'win32':
                subp.terminate()
    
    if __name__ == '__main__':
        main()
    
  • 2

    不幸的是,我'm bound by very strict policies on the disclosure of source code by my employer, so I can' t提供了实际的代码 . 但根据我的口味,最好的解决方案是创建一个子类重写 Popen.wait() 以轮询而不是无限期地等待,并且 Popen.__init__ 接受超时参数 . 一旦你这样做,所有其他 Popen 方法(调用 wait )将按预期工作,包括 communicate .

  • 3

    https://pypi.python.org/pypi/python-subprocess2提供了子进程模块的扩展,允许您等待一段时间,否则终止 .

    所以,等待最多10秒钟的进程终止,否则杀死:

    pipe  = subprocess.Popen('...')
    
    timeout =  10
    
    results = pipe.waitOrTerminate(timeout)
    

    这与windows和unix兼容 . “results”是一个字典,它包含“returnCode”,它是应用程序的返回(如果必须被杀死则为None),以及“actionTaken” . 如果进程正常完成,则为“SUBPROCESS2_PROCESS_COMPLETED”,或者根据所采取的操作设置掩码“SUBPROCESS2_PROCESS_TERMINATED”和SUBPROCESS2_PROCESS_KILLED(有关详细信息,请参阅文档)

  • 0

    如果shell = True,该解决方案会终止进程树,将参数传递给进程(或不传递),具有超时并获取回调的stdout,stderr和process输出(它使用psutil作为kill_proc_tree) . 这是基于SO中发布的几个解决方案,包括jcollado的 . 发表回应Anson和jradice在jcollado答案中的评论 . 在Windows Srvr 2012和Ubuntu 14.04中测试过 . 请注意,对于Ubuntu,您需要将parent.children(...)调用更改为parent.get_children(...) .

    def kill_proc_tree(pid, including_parent=True):
      parent = psutil.Process(pid)
      children = parent.children(recursive=True)
      for child in children:
        child.kill()
      psutil.wait_procs(children, timeout=5)
      if including_parent:
        parent.kill()
        parent.wait(5)
    
    def run_with_timeout(cmd, current_dir, cmd_parms, timeout):
      def target():
        process = subprocess.Popen(cmd, cwd=current_dir, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    
        # wait for the process to terminate
        if (cmd_parms == ""):
          out, err = process.communicate()
        else:
          out, err = process.communicate(cmd_parms)
        errcode = process.returncode
    
      thread = Thread(target=target)
      thread.start()
    
      thread.join(timeout)
      if thread.is_alive():
        me = os.getpid()
        kill_proc_tree(me, including_parent=False)
        thread.join()
    
  • 0

    对于python 2.6,使用gevent

    from gevent.subprocess import Popen, PIPE, STDOUT
    
     def call_sys(cmd, timeout):
          p= Popen(cmd, shell=True, stdout=PIPE)
          output, _ = p.communicate(timeout=timeout)
          assert p.returncode == 0, p. returncode
          return output
    
     call_sys('./t.sh', 2)
    
     # t.sh example
     sleep 5
     echo done
     exit 1
    
  • 4

    python 2.7

    import time
    import subprocess
    
    def run_command(cmd, timeout=0):
        start_time = time.time()
        df = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        while timeout and df.poll() == None:
            if time.time()-start_time >= timeout:
                df.kill()
                return -1, ""
        output = '\n'.join(df.communicate()).strip()
        return df.returncode, output
    
  • 1
    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)
    

相关问题