[Изменено]
2 варианта обработки стандартного вывода из subprocess.Popen
являются stdout="a_file_name"
и stdout=subprocess.PIPE
.
stderr
можно комбинировать с любым из них через stderr=subprocess.STDOUT
.Для subprocess.stderr = STDOUT - Является ли stdout = PIPE лучше, чем stdout = "a_file_name"?
Для того, что я сейчас делаю (тестирование пуганием), мой итоговый код stdout="a_file_name"
немного короче и чище.
Однако, из того, что я видел, кажется, что stdout=PIPE
часто предпочитают другие, но я не уверен во всех причинах.
Если cmd
используется в Popen([cmd, arg], ...)
является исполнимым, который записывает вывод ошибок в stderr
, является stdout=PIPE
как-то лучше, чем stdout="a_file_name"
?
Каковы некоторые плюсы и минусы каждого из них?
- В моем конкретном контексте (см ниже фрагменты кода), 1 преимущество я вижу в использовании
stdout=PIPE
, а неstdout="a_file_name"
в том, что бывший позволит мне легко пропустить запись, пустой файл. - В случае аварии
cmd
может ли 1 из 2 как-то с большей вероятностью получить весь вывод ошибки?
Хотя у меня есть мой конкретный контекст, мне было бы интересно узнать ответ (ы) для более общего случая.
Чтобы лучше объяснить свой контекст, вот мои 2 альтернативные сегменты кода:
import subprocess
import sys
assert sys.version_info >= (3, 3)
# timeout added for subprocess's wait() and communicate() in Python 3.3.
with open('sub_proc1.outerr', 'w') as f_outerr1:
sub_proc1 = subprocess.Popen([cmd, args], stdout=f_outerr1,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
return_code = sub_proc1.wait(timeout=10)
print('*** %s CRASHED with return code: %d.' % (cmd, return_code))
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc1.kill()
против:
...
with open('sub_proc2.outerr', 'w') as f_outerr2:
sub_proc2 = subprocess.Popen([cmd, args], stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
try:
(sub_proc2_out, sub_proc2_err) = sub_proc2.communicate(timeout=10)
print('*** %s CRASHED with return code: %d.' %
(cmd, sub_proc2.poll()))
assert sub_proc2_err is None
# Since stderr was redirected to STDOUT, this should be None.
f_outerr2.write(str(sub_proc2_out or ""))
# Treat 'None' as an empty string).
except subprocess.TimeoutExpired:
print('*** %s succeeded.' % cmd)
sub_proc2.kill()
ОРИГИНАЛЬНЫЙ ПОСТ:
TITLE: подпроцесс: Плюсы и минусы stderr = STDOUT vs. stderr = PIPE?
В 2 основные альтернативы для обработки вывода ошибок из 'subprocess.Popen' кажутся 'STDERR = STDOUT' (с 'стандартный вывод = "some_file"') и 'Stderr = PIPE'.
Для того, что я хочу сделать (тестирование пуганием), мой итоговый код «stderr = STDOUT» немного короче и чище.
Однако, из того, что я прочитал, кажется, что «stderr = PIPE» - , но я не уверен в всех причинах.
Если «Cmd» используется внешний исполняемый файл, который записывает вывод ошибок к «» STDERR, каковы плюсы и минусы использования «Stderr = STDOUT» против «Stderr = PIPE»?
...
Я не думаю, что существует большая разница между этими двумя кодами, если вы ничего не делаете с выходом (кроме записи в файл) в своей тестовой программе. Если вы хотите изучить фактическую информацию о выходе (например, включить ее в ваши вызовы 'print', возможно, или проверить, что она выписывает определенную строку), тогда потребуется использовать' PIPE'. Одним из возможных преимуществ первого кода является то, что он будет чередовать потоки stdout и stderr для вас, если запущенная программа чередуется с ними. С другой стороны, вы не можете разделить эти два выхода! – Blckknght
Благодарим вас за полезный комментарий, Blckknght. Я вижу, что PIPE будет лучшим вариантом, если я захочу изучить фактические данные о выходе. В моем конкретном контексте чередование потоков stdout и stderr в порядке. – Russell
Ваш комментарий заставил меня понять то, чего я раньше не осознавал. Такое чередование возможно при любом способе: стандартный вывод = "a_file_name", STDERR = subprocess.STDOUT или STDOUT = subprocess.PIPE, STDERR = subprocess.STDOUT Аналогично, имеющие стандартный вывод и sterrr потоков без чередования является также возможно с любым из способов: stdout = "file_name_1", stderr = "file_name_2" или stdout = subprocess.PIPE, stderr = subprocess.PIPE – Russell