Jak mogę „przechwycić” Ctrl + C w aplikacji CLI?

85

Jak mogę przechwycić Ctrl + C(co normalnie zabiłoby proces) w aplikacji Java CLI (interfejs wiersza poleceń)?

Czy istnieje rozwiązanie wieloplatformowe (Linux, Solaris, Windows)?

Używam Console„s readLine(), ale jeśli jest to konieczne, można użyć innej metody odczytać znaki ze standardowego wejścia.

ivan_ivanovich_ivanoff
źródło

Odpowiedzi:

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

Powinno to umożliwić przechwycenie sygnału, ale tylko jako krok pośredni, zanim maszyna JVM całkowicie się wyłączy, więc może nie być tym, czym się opiekujesz.

Musisz użyć SignalHandler( sun.misc.SignalHandler), aby przechwycić SIGINTsygnał wyzwalany przez Ctrl+ C(zarówno w systemie Unix, jak i Windows).
Zobacz ten artykuł (pdf, strony 8 i 9).

VonC
źródło
5
@MartijnCourteaux To dzieje się po pięciu latach;) Znalazłem podobne źródło na ten temat i odpowiednio zmieniłem link.
VonC,
@VonC - It's Dead again
Gurwinder Singh
@GurV Który link? Edycja, którą wprowadziłem w kwietniu 2014 ( stackoverflow.com/revisions/ ... ) jest nadal aktualna: nadal możesz pobrać plik pdf ..
VonC
16

Zakładam, że chcesz zamknąć się z wdziękiem i nie zwierać procesu zamykania. Jeśli moje założenie jest poprawne, powinieneś spojrzeć na Shutdown Hooks .

akf
źródło
Nigdy wcześniej nie słyszałem o hakach zamykających. Dziękuję Ci!
ivan_ivanovich_ivanoff
8

Aby móc obsłużyć Ctrl+ Cbez zamykania z jakiegoś powodu, będziesz musiał użyć jakiejś formy obsługi sygnału (ponieważ wejście Ctrl+ Cnie jest w rzeczywistości przekazywane bezpośrednio do twojej aplikacji, ale jest obsługiwane przez system operacyjny, który generuje SIGINT, który jest następnie przekazywany do Javy.

Więcej informacji na temat obsługi sygnałów można znaleźć pod adresem http://www.oracle.com/technetwork/java/javase/signals-139944.html .

(Jeśli chcesz tylko wdzięcznie się zamknąć, wystarczy odpowiedź akf).

Bursztyn
źródło
4

Kilka linków o tym, jak obsłużyć SIGTERM - czyli sygnał, który program dostaje po stronie systemu operacyjnego:

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/

To powinno działać na systemach operacyjnych POSIX - to znaczy, Mac i Unix powinny działać, na Windowsie nie jestem pewien, pamiętam, że słyszałem, że jest również do pewnego stopnia kompatybilny z POSIX, ale może być bardzo varty w różnych wersjach.

Henning
źródło
1
Drugie łącze nie działa. Czy zmieniono go na Oracle pod adresem oracle.com/technetwork/java/javase/tsg-vm-149989.pdf ?
szansa
trzecie połączenie również zawodzi
Hugo Zaragoza