/
process.py
49 lines (42 loc) · 2.02 KB
/
process.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import os
import subprocess
class ShellCommandException(Exception):
pass
def exec_cmd(cmd, throw_on_error=True, env=None, stream_output=False, cwd=None, cmd_stdin=None,
**kwargs):
"""
Runs a command as a child process.
A convenience wrapper for running a command from a Python script.
Keyword arguments:
cmd -- the command to run, as a list of strings
throw_on_error -- if true, raises an Exception if the exit code of the program is nonzero
env -- additional environment variables to be defined when running the child process
cwd -- working directory for child process
stream_output -- if true, does not capture standard output and error; if false, captures these
streams and returns them
cmd_stdin -- if specified, passes the specified string as stdin to the child process.
Note on the return value: If stream_output is true, then only the exit code is returned. If
stream_output is false, then a tuple of the exit code, standard output and standard error is
returned.
"""
cmd_env = os.environ.copy()
if env:
cmd_env.update(env)
if stream_output:
child = subprocess.Popen(cmd, env=cmd_env, cwd=cwd, universal_newlines=True,
stdin=subprocess.PIPE, **kwargs)
child.communicate(cmd_stdin)
exit_code = child.wait()
if throw_on_error and exit_code != 0:
raise ShellCommandException("Non-zero exitcode: %s" % (exit_code))
return exit_code
else:
child = subprocess.Popen(
cmd, env=cmd_env, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE,
cwd=cwd, universal_newlines=True, **kwargs)
(stdout, stderr) = child.communicate(cmd_stdin)
exit_code = child.wait()
if throw_on_error and exit_code != 0:
raise ShellCommandException("Non-zero exit code: %s\n\nSTDOUT:\n%s\n\nSTDERR:%s" %
(exit_code, stdout, stderr))
return exit_code, stdout, stderr