Python subprocess timeout?

后端 未结 10 2115
旧时难觅i
旧时难觅i 2020-12-09 04:06

Is there any argument or options to setup a timeout for Python\'s subprocess.Popen method?

Something like this:

subprocess.Popen([\'..\'], ..., timeout

相关标签:
10条回答
  • 2020-12-09 04:45
    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)
    

    The output of this should be:

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

    where it can be seen that, in the first execution, the process finished correctly (return code 0), while the in the second one the process was terminated (return code -15).

    I haven't tested in windows; but, aside from updating the example command, I think it should work since I haven't found in the documentation anything that says that thread.join or process.terminate is not supported.

    0 讨论(0)
  • 2020-12-09 04:46

    Unfortunately, there isn't such a solution. I managed to do this using a threaded timer that would launch along with the process that would kill it after the timeout but I did run into some stale file descriptor issues because of zombie processes or some such.

    0 讨论(0)
  • 2020-12-09 04:46

    As of Python 3.3, there is also a timeout argument to the blocking helper functions in the subprocess module.

    https://docs.python.org/3/library/subprocess.html

    0 讨论(0)
  • 2020-12-09 04:51

    subprocess.Popen doesn't block so you can do something like this:

    import time
    
    p = subprocess.Popen(['...'])
    time.sleep(20)
    if p.poll() is None:
      p.kill()
      print 'timed out'
    else:
      print p.communicate()
    

    It has a drawback in that you must always wait at least 20 seconds for it to finish.

    0 讨论(0)
提交回复
热议问题