Como posso “interceptar” Ctrl + C em um aplicativo CLI?

85

Como posso interceptar Ctrl + C(o que normalmente encerraria o processo) em um aplicativo Java CLI (interface de linha de comando)?

Existe uma solução multiplataforma (Linux, Solaris, Windows)?

Estou usando Consoleo readLine(), mas, se necessário, poderia usar algum outro método para ler caracteres da entrada padrão.

ivan_ivanovich_ivanoff
fonte

Respostas:

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

Isso deve ser capaz de interceptar o sinal, mas apenas como uma etapa intermediária antes que a JVM desligue completamente, portanto, pode não ser o que você está procurando.

Você precisa usar um SignalHandler( sun.misc.SignalHandler) para interceptar o SIGINTsinal disparado por um Ctrl+ C(no Unix e também no Windows).
Veja este artigo (pdf, páginas 8 e 9).

VonC
fonte
5
@MartijnCourteaux Isso acontece depois de cinco anos;) Eu encontrei uma fonte semelhante sobre o assunto e mudei o link de acordo.
VonC
@VonC - Está morto novamente
Gurwinder Singh
@GurV Qual link? A edição que fiz em abril de 2014 ( stackoverflow.com/revisions/… ) ainda é válida: você ainda pode baixar o arquivo pdf.
VonC
16

Estou assumindo que você deseja desligar normalmente e não causar curto-circuito no processo de desligamento. Se minha suposição estiver correta, você deve consultar os Ganchos de desligamento .

akf
fonte
Nunca ouvi falar de ganchos de desligamento antes. Obrigado!
ivan_ivanovich_ivanoff
8

A fim de ser capaz de lidar com Ctrl+ Csem desligar por algum motivo, você precisará usar alguma forma de tratamento de sinal (uma vez que a entrada Ctrl+ Cnão é realmente passada diretamente para seu aplicativo, mas em vez disso, é tratada pelo sistema operacional que gera um SIGINT que é então passado para Java.

Consulte http://www.oracle.com/technetwork/java/javase/signals-139944.html para obter detalhes sobre o tratamento de sinais.

(Se você deseja apenas desligar normalmente, a resposta de akf será suficiente.)

Âmbar
fonte
4

Alguns links sobre como lidar com o SIGTERM - esse é o sinal que o programa está recebendo no lado do sistema operacional:

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/

Isso deve funcionar em sistemas operacionais POSIX - ou seja, Mac e Unix devem funcionar, em windows não tenho certeza, lembro-me de ouvir que também é compatível com POSIX até certo ponto, mas pode variar muito com versões diferentes.

Henning
fonte
1
O segundo link falha. Ele foi alterado para Oracle em oracle.com/technetwork/java/javase/tsg-vm-149989.pdf ?
chance
o terceiro link também falha
Hugo Zaragoza