Как я могу "перехватить" Ctrl + C в приложении CLI?

Как я могу перехватить Ctrl + C (который обычно убивал бы процесс) в интерфейсе CLI (интерфейс командной строки) Java-приложения?

Существует ли многоплатформенное решение (Linux, Solaris, Windows)?

Я использую Console readLine(), но при необходимости я могу использовать какой-то другой метод для чтения символов со стандартного ввода.

Ответ 1

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

Это должно быть в состоянии перехватить сигнал, но только в качестве промежуточного шага до того, как JVM полностью отключится, поэтому, возможно, это не то, что вам нужно.

Вам нужно использовать SignalHandler (sun.misc.SignalHandler), чтобы перехватить сигнал SIGINT, вызванный Ctrl + C (как в Unix, так и в Windows).
См. в этой статье (pdf, стр. 8 и 9).

Ответ 2

Я предполагаю, что вы хотите изящно завершить работу и не выполнять короткое замыкание процесса выключения. Если мое предположение верно, тогда вы должны посмотреть Shutdown Hooks.

Ответ 3

Чтобы иметь возможность обрабатывать Ctrl + C без каких-либо остановок, вам нужно будет использовать некоторую форму обработки сигналов (поскольку вход Ctrl + C не является фактически передается непосредственно вашему приложению, но вместо этого обрабатывается ОС, которая генерирует SIGINT, который затем передается на Java.

Подробнее о обработке сигналов см. http://www.oracle.com/technetwork/java/javase/signals-139944.html.

(Если вы просто хотите изящно завершить работу, ответ на akf будет достаточным.)

Ответ 4

Некоторые ссылки о том, как обращаться с SIGTERM - это сигнал, который программа получает на стороне ОС:

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/

Это должно работать на операционных системах POSIX, то есть Mac и Unix должны работать, на окнах я не уверен, я помню, что он также совместим с POSIX, но может сильно разноситься с разными версиями.