Comment puis-je «intercepter» Ctrl + C dans une application CLI?

85

Comment puis-je intercepter Ctrl + C(qui normalement tuerait le processus) dans une application Java CLI (interface de ligne de commande)?

Existe-t-il une solution multi-plateforme (Linux, Solaris, Windows)?

J'utilise Console« s readLine(), mais si nécessaire, je pourrais utiliser une autre méthode pour lire les caractères de l' entrée standard.

ivan_ivanovich_ivanoff
la source

Réponses:

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

Cela devrait pouvoir intercepter le signal, mais seulement comme étape intermédiaire avant que la machine virtuelle Java ne s'arrête complètement d'elle-même, donc ce n'est peut-être pas ce que vous recherchez.

Vous devez utiliser un SignalHandler( sun.misc.SignalHandler) pour intercepter le SIGINTsignal déclenché par un Ctrl+ C(sous Unix comme sous Windows).
Voir cet article (pdf, pages 8 et 9).

VonC
la source
5
@MartijnCourteaux Cela se produit après cinq ans;) J'ai trouvé une source similaire sur ce sujet et j'ai changé le lien en conséquence.
VonC le
@VonC - It's Dead again
Gurwinder Singh
@GurV Quel lien? La modification que j'ai faite en avril 2014 ( stackoverflow.com/revisions/… ) est toujours valide: vous pouvez toujours télécharger le fichier pdf ..
VonC
16

Je suppose que vous voulez arrêter gracieusement et ne pas court-circuiter le processus d'arrêt. Si mon hypothèse est correcte, alors vous devriez regarder Shutdown Hooks .

akf
la source
Jamais entendu parler des crochets d'arrêt auparavant. Merci!
ivan_ivanovich_ivanoff
8

Afin de pouvoir gérer Ctrl+ Csans arrêter pour une raison quelconque, vous devrez utiliser une forme de gestion du signal (puisque l' entrée Ctrl+ Cn'est pas réellement transmise directement à votre application, mais est plutôt gérée par le système d'exploitation qui génère un SIGINT qui est ensuite passé à Java.

Voir http://www.oracle.com/technetwork/java/javase/signals-139944.html pour plus de détails sur la gestion des signaux.

(Si vous souhaitez simplement arrêter gracieusement, la réponse d'akf suffira.)

ambre
la source
4

Quelques liens sur la façon de gérer SIGTERM - c'est le signal que le programme reçoit du côté du système d'exploitation:

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/

Cela devrait fonctionner sur les systèmes d'exploitation POSIX - c'est-à-dire que Mac et Unix devraient fonctionner, sous Windows, je ne suis pas sûr, je me souviens avoir entendu dire qu'il est également compatible POSIX dans une certaine mesure, mais pourrait beaucoup varier avec différentes versions.

Henning
la source
1
Le deuxième lien échoue. Est-il remplacé par Oracle sur oracle.com/technetwork/java/javase/tsg-vm-149989.pdf ?
chance le
le troisième lien échoue également
Hugo Zaragoza