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.Popen(
cmd,
stderr=subprocess.STDOUT, # Merge stdout and stderr
stdout=subprocess.PIPE,
shell=True)
communicate
is used to wait for the process to exit:
stdoutdata, stderrdata = proc.communicate()
The subprocess
module does not support timeout--ability to kill a process running for more than X number of seconds--therefore, communicate
may take forever to run.
What is the simplest way to implement timeouts in a Python program meant to run on Windows and Linux?
I had the problem that I wanted to terminate a multithreading subprocess if it took longer than a given timeout length. I wanted to set a timeout in
Popen()
, but it did not work. Then, I realized thatPopen().wait()
is equal tocall()
and so I had the idea to set a timeout within the.wait(timeout=xxx)
method, which finally worked. Thus, I solved it this way:I don't know much about the low level details; but, given that in python 2.6 the API offers the ability to wait for threads and terminate processes, what about running the process in a separate thread?
The output of this snippet in my machine is:
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.
If you're on Unix,
The solution I use is to prefix the shell command with timelimit. If the comand takes too long, timelimit will stop it and Popen will have a returncode set by timelimit. If it is > 128, it means timelimit killed the process.
See also python subprocess with timeout and large output (>64K)