Как остановить передачу 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.

Другие вопросы по тегам