Как остановить передачу SIGINT в подпроцесс в python?
Мой скрипт на python перехватывает сигнал SIGINT с модулем обработки сигналов, чтобы предотвратить преждевременный выход, но этот сигнал передается подпроцессу, который я открываю с помощью Popen. Есть ли способ предотвратить передачу этого сигнала в подпроцесс, чтобы он также не выходил преждевременно, когда пользователь нажимает Ctrl-C?
3 ответа
Вы можете переназначить роль ctrl-c, используя tty
Модуль, позволяющий манипулировать назначением сигналов. Тем не менее, имейте в виду, что если вы не вернете их такими, какими они были до изменения, они будут сохраняться в течение всего сеанса оболочки даже после завершения работы программы.
Вот простой фрагмент кода, который поможет вам начать работу с сохранением ваших старых настроек tty, переназначением ctrl-c на ctrl-x и последующим восстановлением предыдущих настроек tty при выходе.
import sys
import tty
# Back up previous tty settings
stdin_fileno = sys.stdin.fileno()
old_ttyattr = tty.tcgetattr(stdin_fileno)
try:
print 'Reassigning ctrl-c to ctrl-x'
# Enter raw mode on local tty
tty.setraw(stdin_fileno)
raw_ta = tty.tcgetattr(stdin_fileno)
raw_ta[tty.LFLAG] |= tty.ISIG
raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR
# ^X is the new ^C, set this to 0 to disable it entirely
raw_ta[tty.CC][tty.VINTR] = '\x18'
# Set raw tty as active tty
tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)
# Dummy program loop
import time
for _ in range(5):
print 'doing stuff'
time.sleep(1)
finally:
print 'Resetting ctrl-c'
# Restore previous tty no matter what
tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)
Обработчики сигналов наследуются при запуске подпроцесса, поэтому, если вы используете модуль сигналов для игнорирования SIGINT (signal.signal(signal.SIGINT, signal.SIG_IGN)
), то ваш дочерний процесс автоматически также будет.
Однако есть два важных предостережения:
- Вы должны установить обработчик игнорирования, прежде чем создавать дочерний процесс
- Пользовательские обработчики сигналов сбрасываются на обработчики по умолчанию, поскольку дочерний процесс не будет иметь доступа к коду обработчика для его запуска.
Поэтому, если вам нужно настроить обработку SIGINT, а не просто игнорировать ее, вы, вероятно, захотите временно игнорировать SIGINT во время порождения дочернего процесса, а затем (пере) установить свой собственный обработчик сигнала.
Если вы пытаетесь поймать SIGINT и установить флаг, чтобы вы могли выйти в безопасной точке, а не сразу, помните, что когда вы доберетесь до этой безопасной точки, ваш код должен будет вручную очистить его потомков, так как ваш дочерний процесс и любой другой процессы, которые он запускает, будут игнорировать SIGINT.
Для кодовой базы Python 2: подпроцесс не работает.
Правильно это
import subprocess32 as subprocess
См. подпроцесс32
Это бэкпорт модуля подпроцесса Python 3 для использования в Python2. Этот код не тестировался на Windows или других платформах, отличных от POSIX.