Using module 'subprocess' with timeout

后端 未结 29 2424
旧巷少年郎
旧巷少年郎 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:08

    There's an idea to subclass the Popen class and extend it with some simple method decorators. Let's call it 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()
    

提交回复
热议问题