Redirect subprocess stderr to stdout

前端 未结 2 1698
说谎
说谎 2020-12-03 06:44

I want to redirect the stderr output of a subprocess to stdout. The constant STDOUT should do that, shouldn\'t it?

However,

$ python >/dev/null -c         


        
相关标签:
2条回答
  • 2020-12-03 07:18

    Actually, using subprocess.STDOUT does exactly what is stated in the documentation: it redirects stderr to stdout so that e.g.

    proc = subprocess.Popen(self.task["command"], shell=False, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ""
    while (True):
        # Read line from stdout, break if EOF reached, append line to output
        line = proc.stdout.readline()
        line = line.decode()
        if (line == ""): break
        output += line
    

    results in variable output containing the process' output from both stdout and stderr.

    stderr=subprocess.STDOUT redirects all stderr output directly to stdout of the calling process, which is a major difference.

    0 讨论(0)
  • 2020-12-03 07:23

    A close read of the source code gives the answer. In particular, the documentation is misleading when it says:

    subprocess.STDOUT
    Special value that (...) indicates that standard error should go into the same handle as standard output.

    Since stdout is set to "default" (-1, technically) when stderr=subprocess.STDOUT is evaluated, stderr is set to "default" as well. Unfortunately, this means that stderr output still goes to stderr.

    To solve the problem, pass in the stdout file instead of subprocess.STDOUT:

    $ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
                            stderr=sys.stdout.buffer)'
    

    Or, for compatibility with legacy 2.x versions of Python:

    $ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
                            stderr=sys.stdout.fileno())'
    
    0 讨论(0)
提交回复
热议问题