在程序关闭期间在 Python 中捕获 KeyboardInterrupt

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21120947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 22:06:13  来源:igfitidea点击:

Catching KeyboardInterrupt in Python during program shutdown

pythonkeyboardinterrupt

提问by Dan

I'm writing a command line utility in Python which, since it is production code, ought to be able to shut down cleanly without dumping a bunch of stuff (error codes, stack traces, etc.) to the screen. This means I need to catch keyboard interrupts.

我正在用 Python 编写一个命令行实用程序,因为它是生产代码,所以应该能够干净利落地关闭而不会将一堆东西(错误代码、堆栈跟踪等)转储到屏幕上。这意味着我需要捕捉键盘中断。

I've tried using both a try catch block like:

我试过同时使用 try catch 块,例如:

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print 'Interrupted'
        sys.exit(0)

and catching the signal itself (as in this post):

并捕获信号本身(如本文所述):

import signal
import sys

def sigint_handler(signal, frame):
    print 'Interrupted'
    sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)

Both methods seem to work quite well during normal operation. However, if the interrupt comes during cleanup code at the end of the application, Python seems to always print something to the screen. Catching the interrupt gives

在正常操作期间,这两种方法似乎都非常有效。但是,如果在应用程序结束时的清理代码期间出现中断,Python 似乎总是在屏幕上打印一些内容。捕获中断给出

^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored

whereas handling the signal gives either

而处理信号给出

^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored

or

或者

^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored

Not only are these errors ugly, they're not very helpful (especially to an end user with no source code)!

这些错误不仅难看,而且也不是很有帮助(尤其是对于没有源代码的最终用户)!

The cleanup code for this application is fairly big, so there's a decent chance that this issue will be hit by real users. Is there any way to catch or block this output, or is it just something I'll have to deal with?

这个应用程序的清理代码相当大,所以这个问题很可能会被真实用户击中。有什么方法可以捕获或阻止此输出,还是只是我必须处理的事情?

回答by Dan Getz

You could ignore SIGINTs after shutdown starts by calling signal.signal(signal.SIGINT, signal.SIG_IGN)before you start your cleanup code.

您可以通过signal.signal(signal.SIGINT, signal.SIG_IGN)在启动清理代码之前调用来在关闭启动后忽略 SIGINT 。

回答by Dan Hogan

Checkout this thread, it has some useful information about exiting and tracebacks.

签出这个线程,它有一些关于退出和回溯的有用信息。

If you are more interested in just killing the program, try something like this (this will take the legs out from under the cleanup code as well):

如果您对杀死程序更感兴趣,请尝试这样的操作(这也会从清理代码中取出腿):

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('Interrupted')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)