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?
In Python 3.3+:
from subprocess import STDOUT, check_output
output = check_output(cmd, stderr=STDOUT, timeout=seconds)
output
is a byte string that contains command's merged stdout, stderr data.
check_output
raises CalledProcessError
on non-zero exit status as specified in the question's text unlike proc.communicate()
method.
I've removed shell=True
because it is often used unnecessarily. You can always add it back if cmd
indeed requires it. If you add shell=True
i.e., if the child process spawns its own descendants; check_output()
can return much later than the timeout indicates, see Subprocess timeout failure.
The timeout feature is available on Python 2.x via the subprocess32
backport of the 3.2+ subprocess module.