Catching KeyboardInterrupt en Python durante el cierre del programa
python catch keyboard interrupt (2)
Puede ignorar los SIGINT después de que el apagado comience llamando a signal.signal(signal.SIGINT, signal.SIG_IGN)
antes de iniciar el código de limpieza.
Estoy escribiendo una utilidad de línea de comandos en Python que, dado que es un código de producción, debería ser capaz de cerrarse limpiamente sin tirar un montón de cosas (códigos de error, rastros de pila, etc.) a la pantalla. Esto significa que necesito atrapar interrupciones del teclado.
Intenté usar un bloque try catch como:
if __name__ == ''__main__'':
try:
main()
except KeyboardInterrupt:
print ''Interrupted''
sys.exit(0)
y atrapando la señal en sí (como en esta publicación ):
import signal
import sys
def sigint_handler(signal, frame):
print ''Interrupted''
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
Ambos métodos parecen funcionar bastante bien durante el funcionamiento normal. Sin embargo, si la interrupción se produce durante el código de limpieza al final de la aplicación, Python parece que siempre imprime algo en la pantalla. La captura de la interrupción da
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
mientras que manejar la señal da cualquiera
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
o
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
Estos errores no solo son feos, no son muy útiles (especialmente para un usuario final sin código fuente).
El código de limpieza para esta aplicación es bastante grande, por lo que hay una posibilidad decente de que los usuarios reales acierten este problema. ¿Hay alguna manera de atrapar o bloquear esta salida, o es solo algo con lo que tendré que lidiar?
Verifique este hilo , tiene información útil sobre salidas y trazas.
Si estás más interesado en simplemente matar el programa, prueba algo como esto (esto también eliminará las patas del código de limpieza):
if __name__ == ''__main__'':
try:
main()
except KeyboardInterrupt:
print(''Interrupted'')
try:
sys.exit(0)
except SystemExit:
os._exit(0)