Python – обрабатывать CTRL+D с помощью «сигнала импорта»

В настоящее время я могу обрабатывать CTRL+C через:

def hand_inter(signum, frame):
    print 'hey, nice job.'

signal.signal(signal.SIGINT, hand_inter)

Однако я должен также обрабатывать CTRL+D, но не могу найти соответствующий вызов "signal.CTRL+D" для signum.


person Community    schedule 07.03.2014    source источник


Ответы (1)


Ctrl+D — это не сигнал, это конец файла.

Если у вас есть интерактивная программа, вы, скорее всего, будете читать STDIN, а Ctrl+D — это то, как пользователь говорит, что ввод окончен. Вне этого контекста оно не имеет особого значения.

Код, который выполняется после этого, обычно является кодом после "readline" или аналогичного вызова. Это эквивалентно чтению любого другого файла и обнаружению того, что он закончился, и нет больше данных для чтения - соответствующий вызов даст вам указание на это.

Например, это может быть простая интерактивная программа:

import sys

while True:
    line = sys.stdin.readline()    # readline will return "" on EOF
    if line:
        do_something_with(line)    # * if user just pressed Enter line will
                                   #   be "\n", i.e. still True
    else:                          # * user pressed C-D, i.e. stdin has been
        sys.exit(0)                #   closed readline call must have returned ""

С другой стороны, Ctrl+C отличается тем, что пользователь говорит своему терминалу завершить запущенный процесс. Это может произойти в любой момент, независимо от того, запрашивает ли процесс какие-либо данные или вообще заботится о внешнем мире.

Поскольку процесс не может ожидать этого, вам нужно signal установить так называемые ловушки, которые представляют собой механизм, предоставляемый ОС, чтобы позволить процессам сказать: «Если вы когда-нибудь захотите меня уволить, пожалуйста, просто выполните это вместо этого ...» (что может быть чем угодно, включая ничего, то есть просто игнорирование сигнала). Исключения — это специальные сигналы, такие как SIGKILL, которые не могут быть перехвачены процессом.

person Alois Mahdal    schedule 07.03.2014
comment
Я реализую сервер чата с клиентским кодом, который активно прослушивает при подключении и отправляет сообщение при нажатии «ввод». Мне необходимо разорвать соединение с помощью команды «CTRL-D». - person ; 07.03.2014
comment
@JoeyDiNardo посмотри на мой пример. (Ожидайте ошибок, так как я написал это из головы, но вы поняли... :)) - person Alois Mahdal; 07.03.2014
comment
Хм, с sys.exit() нажатие ctrl+d, кажется, вообще ничего не делает. Когда я установил его для печати «тест», он работает безупречно. У меня есть отдельная тема, может в этом дело? msg = sys.stdin.readline() if msg: s.send(msg) prompt() else: sys.exit() - person ; 07.03.2014
comment
странно, я просто скопировал свой код, добавил do_something... и он отлично работает. Может быть, попробуйте написать простой текстовый файл и отправить его на стандартный ввод, используя перенаправление оболочки, например ./script.py < simple_file.txt - person Alois Mahdal; 07.03.2014
comment
Что ж, если вы используете потоки (и, поскольку вы говорите, что это для работы в сети, я думаю, вы используете потоковый TCP-сервер Python), исходный код может не работать, поскольку, например, поток может ждать другого и т. д. становится немного сложнее. :) - person Alois Mahdal; 07.03.2014
comment
Исправлено с помощью os._exit(0) вместо sys. Спасибо еще раз :). - person ; 07.03.2014
comment
Я не уверен, как правильно в вашем случае, но я знаю, что os._exit(0) не рекомендуется. Например, он, вероятно, не будет очищаться должным образом, поэтому у вас могут возникнуть другие проблемы, такие как обломки файлов или занятые сокеты, если вы часто выходите и запускаете процесс (это во многом зависит от вашей ОС). - person Alois Mahdal; 07.03.2014