Catch stderr in subprocess.check_call without usin

2019-08-31 04:49发布

问题:

I'd like to do the following:

  • shell out to another executable from Python, using subprocess.check_call
  • catch the stderr of the child process, if there is any
  • add the stderr output to the CalledProcessError exception output from the parent process.

In theory this is simple. The check_call function signature contains a kwarg for stderr:

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

However, immediately below that the documentation contains the following warning:

Note: Do not use stdout=PIPE or stderr=PIPE with this function. As the pipes are not being read in the current process, the child process may block if it generates enough output to a pipe to fill up the OS pipe buffer.

The problem is that pretty much every example I can find for getting stderr from the child process mentions using subprocess.PIPE to capture that output.

How can you capture stderr from the child process without using subprocess.PIPE?

回答1:

stdout and stderr can be assigned to almost anything that can receive data like a file-handle. you can even supply an open file_handle for writing to stdout and stderr:

file_handle = open('some_file', 'w')

subprocess.check_call(args, *, stdin=None, stdout=file_handle, stderr=file_handle, shell=False)

now every line of output goes to same file, or you could have a different file for each.

stdin also reads like a filehandle, using the next() to read each line as an input command to be sent on in addition to the initial args.

its a very robust function.