¿Cómo puedo “interceptar” Ctrl + C en una aplicación CLI?

85

Como puedo interceptar Ctrl + C(que normalmente mataría el proceso) en una aplicación Java CLI (interfaz de línea de comandos)?

¿Existe una solución multiplataforma (Linux, Solaris, Windows)?

Estoy usando Console's readLine(), pero si es necesario, podría usar algún otro método para leer caracteres de la entrada estándar.

ivan_ivanovich_ivanoff
fuente

Respuestas:

121
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() { /*
       my shutdown code here
    */ }
 });

Esto debería poder interceptar la señal, pero solo como un paso intermedio antes de que la JVM se apague completamente, por lo que es posible que no sea lo que está buscando.

Necesita usar un SignalHandler( sun.misc.SignalHandler) para interceptar la SIGINTseñal disparada por un Ctrl+ C(tanto en Unix como en Windows).
Consulte este artículo (pdf, páginas 8 y 9).

VonC
fuente
5
@MartijnCourteaux Eso sucede después de cinco años;) He encontrado una fuente similar sobre ese tema y he cambiado el enlace en consecuencia.
VonC
@VonC - Está muerto de nuevo
Gurwinder Singh
@GurV ¿Qué enlace? La edición que hice en abril de 2014 ( stackoverflow.com/revisions/… ) sigue siendo válida: aún puede descargar el archivo pdf ..
VonC
16

Supongo que desea apagar correctamente y no cortocircuitar el proceso de apagado. Si mi suposición es correcta, entonces debería mirar Shutdown Hooks .

akf
fuente
Nunca antes había oído hablar de los ganchos de cierre. ¡Gracias!
ivan_ivanovich_ivanoff
8

Para poder manejar Ctrl+ Csin apagar por alguna razón, necesitará usar alguna forma de manejo de señales (ya que la entrada Ctrl+ Cno se pasa directamente a su aplicación, sino que es manejada por el sistema operativo que genera un SIGINT que luego se pasa a Java.

Consulte http://www.oracle.com/technetwork/java/javase/signals-139944.html para obtener detalles sobre el manejo de señales.

(Si solo desea cerrar con elegancia, la respuesta de akf será suficiente).

Ámbar
fuente
4

Algunos enlaces sobre cómo manejar SIGTERM, esa es la señal que el programa está recibiendo en el lado del sistema operativo:

http://blog.webinf.info/2008/08/intercepting-sigterm.html

http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html

http://www.ibm.com/developerworks/java/library/i-signalhandling/

Eso debería funcionar en los sistemas operativos POSIX, es decir, Mac y Unix deberían funcionar, en Windows no estoy seguro, recuerdo haber oído que también es compatible con POSIX hasta cierto punto, pero podría variar mucho con diferentes versiones.

Henning
fuente
1
El segundo enlace falla. ¿Se cambió a Oracle en oracle.com/technetwork/java/javase/tsg-vm-149989.pdf ?
oportunidad
El tercer enlace también falla
Hugo Zaragoza