Skip to content

Instantly share code, notes, and snippets.

@AnIrishDuck
Created March 20, 2013 20:34
Show Gist options
  • Save AnIrishDuck/5208183 to your computer and use it in GitHub Desktop.
Save AnIrishDuck/5208183 to your computer and use it in GitHub Desktop.
Similar to subprocess.check_output, but returns the results of stdout and stderr separately.
def check_out_and_err(*args, **kwargs):
"""
Pipe from BOTH stdout and stderr. Avoids deadlock by performing nonblocking
reads. Why this isn't in the stdlib is beyond me.
"""
if 'stdout' in kwargs or 'stderr' in kwargs:
raise ValueError("stdout/stderr arguments not allowed.")
with nested(pipe("r"), pipe("r")) as ((rout, wout), (rerr, werr)):
process = subprocess.Popen(stdout=wout, stderr=werr, *args, **kwargs)
output = {rout: [], rerr: []}
prev = ""
while process.poll() is None:
ready, _, _ = select.select([rout, rerr], [], [], 0.2)
for fd in ready:
output[fd].append(os.read(fd, 1024))
output = (''.join(output[rout]), ''.join(output[rerr]))
code = process.poll()
if code:
cmd = kwargs.get("args")
if cmd is None:
cmd = args[0]
raise subprocess.CalledProcessError(code, cmd, output=output)
return output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment