kdb
kdb

Reputation: 4426

Redirect subprocess stdout to stderr

A standard feature Python's subprocess API is to combine STDERR and STDOUT by using the keyword argument

stderr = subprocess.STDOUT

But currently I need the opposite: Redirect the STDOUT of a command to STDERR. Right now I am doing this manually using subprocess.getoutput or subprocess.check_output and printing the result, but is there a more concise option?

Upvotes: 1

Views: 590

Answers (1)

Daniel McLaury
Daniel McLaury

Reputation: 4293

Ouroborus mentions in the comments that we ought to be able to do something like

subprocess.run(args, stdout = subprocess.STDERR)

However, the docs don't mention the existence of subprocess.STDERR, and at least on my installation (3.8.10) that doesn't actually exist.

According to the docs,

stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object with a valid file descriptor, and None.

Assuming you're on a UNIX-type system (and if you're not, I'm not sure what you're planning on doing with stdout / stderr anyway), the file descriptors for stdin/stdout/stderr are always the same:

  • 0 is stdin
  • 1 is stdout
  • 2 is stderr
  • 3+ are used for fds you create in your program

So we can do something like

subprocess.run(args, stdout = 2)

to run a process and redirect its stdout to stderr.

Of course I would recommend you save that as a constant somewhere instead of just leaving a raw number 2 there. And if you're on Windows or something you may have to do a little research to see if things work exactly the same.

Update:

A subsequent search suggests that this numbering convention is part of POSIX, and that Windows explicitly obeys it.

Update:

@kdb points out in the comments that sys.stderr will typically satisfy the "an existing file object with a valid file descriptor" condition, making it an attractive alternative to using a raw fd here.

Upvotes: 2

Related Questions