Dun Peal
Dun Peal

Reputation: 17739

How to unify stdout and stderr, yet be able to distinguish between them?

I'd like to produce a readable HTML report of a process run. Towards that end, I'd like to track both stdout and stderr, and output them interleaved, yet distinguished - for example, the log will show them both combined according to the order they were emitted, but with stdout in black and stderr in bold red.

I can readily see a solution that will keep them distinguished: just redirect each to subprocess.PIPE. Of course, then they can't be recombined in order. It's also easy to unify them in order: just redirect stderr to subprocess.STDOUT. However, then they will be indistinguishable.

Thus getting the outputs to be either distinguished or combined in order is straightforward, but getting both is not.

What's the way to do that in Python?

Upvotes: 1

Views: 406

Answers (1)

Mark Harrison
Mark Harrison

Reputation: 304662

You can use select() to multiplex the output. Suppose you have stdout and stderr being captured in pipes, this code will work:

import select
import sys

inputs = set([pipe_stdout, pipe_stderr])

while inputs:
  readable, _, _ = select.select(inputs, [], [])
  for x in readable:
    line = x.readline()
    if len(line) == 0:
      inputs.discard(x)
    if x == pipe_stdout
      print 'STDOUT', line
    if x == pipe_stderr
      print 'STDERR', line

Upvotes: 2

Related Questions