This has probably been asked but I cannot find anything regarding a subprocess.call timeout when using python 2.7
- 
                    3have a look into: http://stackoverflow.com/questions/1191374/subprocess-with-timeout – mortymacs Apr 25 '14 at 08:39
5 Answers
A simple way I've always done timeouts with 2.7 is utilizing subprocess.poll() alongside time.sleep() with a delay. Here's a very basic example:
import subprocess
import time
x = #some amount of seconds
delay = 1.0
timeout = int(x / delay)
args = #a string or array of arguments
task = subprocess.Popen(args)
#while the process is still executing and we haven't timed-out yet
while task.poll() is None and timeout > 0:
     #do other things too if necessary e.g. print, check resources, etc.
     time.sleep(delay)
     timeout -= delay
If you set x = 600, then your timeout would amount to 10 minutes. While task.poll() will query whether or not the process has terminated. time.sleep(delay) will sleep for 1 second in this case, and then decrement the timeout by 1 second. You can play around with that part to your heart's content, but the basic concept is the same throughout.
Hope this helps!
subprocess.poll() https://docs.python.org/2/library/subprocess.html#popen-objects
 
    
    - 137,073
- 23
- 153
- 219
 
    
    - 209
- 2
- 7
- 
                    4This doesn't kill the process. You need to add os.killpg(os.getpgid(task.pid), signal.SIGTERM) – Aaron Swan Feb 02 '18 at 20:44
- 
                    
- 
                    if you don't change the process group of the new task, os.killpg(os.getpgid(task.pid) may kill all the processes with the same pg, not only the process executed by subprocess.Popen() and its children(!) – Gianni Aug 30 '22 at 10:14
You could install subprocess32 module mentioned by @gps -- the backport of the subprocess module from Python 3.2/3.3 for use on 2.x.  It works on Python 2.7 and it includes timeout support from Python 3.3.
subprocess.call() is just Popen().wait() and therefore to interrupt a long running process in timeout seconds:
#!/usr/bin/env python
import time
from subprocess import Popen
p = Popen(*call_args)
time.sleep(timeout)
try:
    p.kill()
except OSError:
    pass # ignore
p.wait()
If the child process may end sooner then a portable solution is to use Timer() as suggested in @sussudio's answer:
#!/usr/bin/env python
from subprocess import Popen
from threading import Timer
def kill(p):
    try:
        p.kill()
    except OSError:
        pass # ignore
p = Popen(*call_args)
t = Timer(timeout, kill, [p])
t.start()
p.wait()
t.cancel()
On Unix, you could use SIGALRM as suggested in @Alex Martelli's answer:
#!/usr/bin/env python
import signal
from subprocess import Popen
class Alarm(Exception):
    pass
def alarm_handler(signum, frame):
    raise Alarm
signal.signal(signal.SIGALRM, alarm_handler)
p = Popen(*call_args)
signal.alarm(timeout)  # raise Alarm in 5 minutes
try:
    p.wait()
    signal.alarm(0)  # reset the alarm
except Alarm:
    p.kill()
    p.wait()
To avoid using threads and signals here, subprocess module on Python 3 uses a busy loop with waitpid(WNOHANG) calls on Unix and winapi.WaitForSingleObject() on Windows.
You can try to use "easyprocess":
https://github.com/ponty/EasyProcess
It has many features that you need like "timeout".
 
    
    - 3,456
- 3
- 27
- 53
You can use subprocess32 mentioned by @gps, which is backport of the subprocess standard library module from Python 3.2 - 3.5 for use on Python 2.
Firstly, install the subprocess32 module:
pip install subprocess32
Here's a code snippet:
>>> import subprocess32
>>> print subprocess32.check_output(["python", "--version"])
Python 2.7.12
>>> subprocess32.check_output(["sleep", "infinity"], timeout=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/subprocess32.py", line 340, in check_output
    raise TimeoutExpired(process.args, timeout, output=output)
subprocess32.TimeoutExpired: Command '['sleep', 'infinity']' timed out after 3 seconds
Notice, default timeout=None, which means never timeout.
 
    
    - 1,144
- 12
- 15
In python 3.3 timeout argument was added.
https://docs.python.org/3/library/subprocess.html#subprocess.call
 
    
    - 1,094
- 6
- 12
 
     
    