Отсутствуют последние несколько строк вывода подпроцесса при работе без оболочки = True - PullRequest
1 голос
/ 06 августа 2020

Я запускаю простой сценарий Python 3.6 через подпроцесс другого сценария Python 3.6. Я захватываю SIGINT в исходном процессе, чтобы передать его подпроцессу. Это просто для тестирования модуля, который в конечном итоге будет обертывать другие вещи, но это не слишком важно.

Когда я запускаю подпроцесс без оболочки и отправляю SIGINT, чтобы остановить его, вывод иногда полностью отсутствует трассировка из подпроцесса, в других случаях она просто содержит строку Traceback (most recent call last):, а иногда она содержит полную трассировку.

Я использую Popen, но я также подтвердил, что то же самое происходит при использовании функции communication () или check_output & co.

Однако вот неприятность: если я установил shell=True, я всегда получаю полную трассировку при отправке SIGINT в подпроцесс.

Минимальный пример

producer.py

#!/usr/bin/env python3
import sys
import signal
import time

for number in range(100):
    sys.stderr.write(str(number) + 'this is line ' + str(number) + '\n')
    time.sleep(0.01)
    sys.stderr.flush()

consumer.py

import subprocess
import signal
import sys
import time

process = subprocess.Popen(['./producer.py'],
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    bufsize=1,
    #shell=True,
    encoding="latin-1",
    universal_newlines=True)

def stop_process(a,b):
    process.send_signal(signal.SIGINT)

old_handler = signal.signal(signal.SIGINT, stop_process)
s, e =  process.communicate()
print(s)
print('-----')
print(e)

Попробуйте запустить python3 consumer.py и в любой момент нажать CTRL + C . Если вы попробуете несколько раз, вы увидите различные варианты поведения, которые я перечислил. Теперь попробуйте еще раз после раскомментирования shell=True в потребителе, и вы должны каждый раз получать полную трассировку.

Кто-нибудь знает, почему это так? Я подозреваю python махинаций переводчика, но я хотел бы понять, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...