Отправка SIGINT процессу, запущенному из Python, не дает того же результата, что и при запуске процесса из оболочки - PullRequest
0 голосов
/ 19 ноября 2018

Я пишу скрипт, который должен запускать интерактивную оболочку сторонней программы из python в linux (сторонней программой является Stata). Целью скрипта является управление stdin и stdout интерактивной оболочки, чтобы я мог получить к нему доступ из редактора и других скриптов.

При запуске из оболочки Linux, Stata запускает интерактивную оболочку, в которой вы можете запускать команды Stata. Когда я нажимаю control + C или другим способом отправляю сигнал SIGINT в Stata, он прекращает выполнение текущей команды и возвращается в интерактивную оболочку, но не останавливает процесс Stata. Я хочу повторить это поведение для Stata, запущенной из python.

Когда я отправляю сигнал SIGINT процессу Stata, запущенному из python, он прерывает процесс, а не останавливает выполнение текущей команды.

Поведение в оболочке:

> /usr/local/stata14/stata
(...other stuff...)
. forval i = 1/100000 {
  2. sleep 10
  3. di "`i'"
  4. }
1
2
3
4
(I hit CTRL+C)
--Break--
r(1);
. 

Следующая программа на Python запускает Stata из Python:

def handler(signum, frame):
   stata.send_signal(signal.SIGINT)
signal.signal(signal.SIGINT, handler)

stata = subprocess.Popen(["/usr/local/stata14/stata"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setpgrp)

(... other stuff hat handles forwarding stata.stdout to sys.stdout in a separate thread...)

while true:
   time.sleep(0.1)
   userinput = raw_input(". ")
   print(userinput, file=stata.stdin)
   stata.stdin.flush()
   print(stata.poll())

с тем же циклом for, запущенным в подпроцессе, выдает:

> /usr/local/stata14/stata
. forval i = 1/100000 {
  2. sleep 10
  3. di "`i'"
  4. }
1
2
3
4
-2
-2
-2

и любая дальнейшая попытка записи в stata.stdin приводит к

print(userinput, file=stata.stdin)
IOError: [Errno 32] Broken pipe

Кто-нибудь понимает, почему это происходит? Я уже пытался использовать подпроцесс. Открыть с shell = True. В этом случае Popen запускает процесс sh и процесс Stata. Если я отправляю SIGINT процессу sh, ничего не происходит. Если я отправлю его в Stata, возникнет та же проблема, что и с shell = False.

Заранее спасибо.

...