Задать вопрос

Как перехватить traceback из subprocess?

Запускаю дочерний процесс longlife без ожидания завершения, может возникнуть исключения например при импорте библиотек дочернего процесса.
Можно воспользоваться такой структурой
process = subprocess.Popen(script_exec, universal_newlines=True, stderr=subprocess.PIPE), 
stdout, stderr = process.communicate(timeout=5)

и достать ошибку из stderr и записать в logger, использую таймаут для того чтобы успели отработать ошибки импорта дочернего процесса, дальше в принципе мне не интересно, да и блокировать процесс не хотелось бы вообще, но дочерний процесс устанавливает библиотеки которые тянут файлы из интернета и все это выводиться с помощью tqdm, естественно открытый PIPE не закрывается и дочерний процесс зависает из за deadlock переполнения буфера. Если не использовать PIPE, то traceback вываливается в консоль главного процесса и как его перехватить не представляю, если использовать модуль traceback, то возвращает None, догадываюсь потому как traceback вываливается в дочернем процессе.
Чтобы обойтись без использования PIPE и предотвратить переполнение буфера, единственно, что пришло мне в голову.
это писать в файл вместо PIPE и оттуда читать traceback, если процесс завершился в первые 5 секунд
stderr_file = open('stderr', 'w')
process= subprocess.Popen(script_exec, universal_newlines=True, stderr=stderr_file)
time.sleep(5)
if master_api_process.poll():
    with open('stderr') as stderr_read_file:
        print(stderr_read_file.read())
stderr_file.close()

собственно вопрос как вытащить traceback из subprocess не используя PIPE, либо какой-то альтернативный вариант, можно конечно еще вызывать это подпроцесс сначала в каком нибуть subprocess.check_call() с таймаутом и смотреть не было ли traceback в нем, а потом уже запускать в subprocess.Popen() как longlife процесс, но по-моему это совсем перебор.
  • Вопрос задан
  • 136 просмотров
Подписаться 1 Сложный 2 комментария
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Если я верно понял, что пробелма в синхронном вводе-выводе при общении с дочерним процессом, то я бы посмотрел в сторону asyncio, чтобы анализировать полученное содержимое stderr постепенно, по мере его появления. Может, оверкилл, но должно сработать.
Вот примерная идея, найденная на stackoverflow.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы