Перенаправить подпроцесс stderr в стандартный вывод

Я хочу перенаправить вывод stderr подпроцесса на стандартный вывод. Постоянная STDOUT должен сделать это, не так ли?

Тем не мение,

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

действительно выводит что-то. Почему это так, и как я могу получить сообщение об ошибке на стандартный вывод?

2 ответа

Решение

Внимательное прочтение исходного кода дает ответ. В частности, документация вводит в заблуждение, когда говорится:

subprocess.STDOUT
Специальное значение, которое (...) указывает, что стандартная ошибка должна идти в том же дескрипторе, что и стандартный вывод.

Так как стандартный вывод установлен на "по умолчанию" (-1технически) когда stderr=subprocess.STDOUT оценивается, stderr также устанавливается по умолчанию. К сожалению, это означает, что вывод stderr все еще идет в stderr.

Чтобы решить проблему, передайте файл stdout вместо subprocess.STDOUT:

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

Или для совместимости с устаревшими версиями Python 2.x:

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

На самом деле, используя subprocess.STDOUT делает именно то , что указано в документации: он перенаправляет stderr в stdout так, чтобы, например,

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

приводит к переменной output содержащий вывод процесса из stdout и stderr.

stderr=subprocess.STDOUT перенаправляет весь вывод stderr непосредственно на стандартный вывод вызывающего процесса, что является существенным отличием.

Другие вопросы по тегам