+ex_res = namedtuple('SubprocResult', ['out', 'err', 'proc', 'rc'])
+
+def run(cmd, check=True, input=None, **kwargs):
+ """Run a subprocess as per subprocess.Popen(cmd, **kwargs) followed by
+ communicate(input=input). If check is true, then throw an
+ exception if the subprocess exits with non-zero status. Return a
+ SubprocResult tuple.
+
+ """
+ if input:
+ assert 'stdin' not in kwargs
+ kwargs['stdin'] = PIPE
+ p = Popen(cmd, **kwargs)
+ out, err = p.communicate(input=input)
+ if check and p.returncode != 0:
+ raise Exception('subprocess %r failed with status %d%s'
+ % (' '.join(map(quote, cmd)), p.returncode,
+ (', stderr: %r' % err) if err else ''))
+ return ex_res(out=out, err=err, proc=p, rc=p.returncode)
+