2

Я пытаюсь избежать последствий нажатия Ctrl+C в командном файле, что-то похожее на Как подавить подтверждение «Завершить пакетное задание (Y/N)»? , Однако в моем случае я хочу, чтобы сигнал обрабатывался моим базовым сценарием. Мой командный файл выглядит так:

@ECHO off
setlocal
set "script_path=%~dp0"
set "script_path=%script_path%myscript.py"
python "%script_path%" %*
endlocal

Я хотел бы иметь возможность нажать Ctrl+C и обработать его как ошибку KeyboardInterrupt в myscript.py вместо немедленного прекращения процесса. Прямо сейчас, если я нажму Ctrl+C, я получу:

forrtl: error (200): program aborting due to control-C event
Image              PC        Routine            Line        Source
libifcoremd.dll    0FCA7CB8  Unknown               Unknown  Unknown
KERNELBASE.dll     76411C99  Unknown               Unknown  Unknown
KERNEL32.DLL       74A68484  Unknown               Unknown  Unknown
ntdll.dll          77C2305A  Unknown               Unknown  Unknown
ntdll.dll          77C2302A  Unknown               Unknown  Unknown
Terminate batch job (Y/N)?

Я пробовал следующие варианты:

  1. Замените python "%script_path%" %* на start python "%script_path%" %* . Это запускает новую оболочку, которая на самом деле хороша тем, что я пытаюсь сделать. Стандартный ввод, кажется, работает правильно в новой оболочке. Однако Ctrl+C имеет тот же эффект, что и раньше, и новая оболочка немедленно умирает. Добавление команды exit к концу пакетного файла, похоже, также не имеет никакого эффекта.
  2. Замените python "%script_path%" %* на start /b python "%script_path%" %* . Это просто запускает работу в фоновом режиме в той же оболочке. Ctrl+C по- прежнему просто убивает работу, и теперь стандартный ввод не работает правильно.

Дополнительное примечание:

Мой скрипт Python время от времени должен читать пользовательский ввод из sys.stdin . Сценарий читает некоторые входные данные, а затем обрабатывает их так, чтобы пользователь мог нажать Ctrl+C. Идея состоит в том, чтобы сделать что-то осмысленное в предложении except KeyboardInterrupt: вместо того, чтобы просто смотреть как сценарий умирает.

1 ответ1

0

Ctrl - C - SIGINT так что вы можете поймать его, используя модуль signal внутри скрипта Python:

import signal
import time

def handler(signum, frame):
    print 'Got Ctrl-C'
    #you code handling the Ctrl-C

signal.signal(signal.SIGINT, handler)
# your code

Имейте в виду, что в Python 2.7 для Windows была ошибка, помеченная как Won't fix , поэтому вам следует использовать Python 3.3+.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .