Перенаправить подпроцесс stderr в stdout
Я хочу перенаправить вывод stderr подпроцесса на stdout. Постоянная STDOUT
должна делать это, не так ли?
Однако
$ python >/dev/null -c 'import subprocess;\
subprocess.call(["ls", "/404"],stderr=subprocess.STDOUT)'
выводит что-то. Почему это так, и как мне получить сообщение об ошибке на stdout?
Ответы
Ответ 1
В результате ответа читается исходный код. В частности, документация вводит в заблуждение, когда говорится:
subprocess.STDOUT
Специальное значение, которое (...) указывает, что стандартная ошибка должна входить в один и тот же дескриптор в качестве стандартного вывода.
Так как stdout устанавливается на "по умолчанию" (-1
, технически), когда stderr=subprocess.STDOUT
оценивается, stderr также устанавливается на "default". К сожалению, это означает, что вывод stderr все еще идет на stderr.
Чтобы решить проблему, перейдите в файл stdout вместо subprocess.STDOUT
:
$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
stderr=sys.stdout.buffer)'
Или, для совместимости с устаревшими версиями версии 2.x Python:
$ python >/dev/null -c 'import subprocess,sys;subprocess.call(["ls", "/404"],
stderr=sys.stdout.fileno())'
Ответ 2
На самом деле, используя 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
выводит вывод, содержащий вывод процесса, как из stdout, так и из stderr.
stderr=subprocess.STDOUT
перенаправляет весь вывод stderr напрямую на стандартный вывод вызывающего процесса, что является существенным отличием.