This has probably been asked but I cannot find anything regarding a subprocess.call timeout when using python 2.7
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.