如何在CLI应用程序中“截取”Ctrl+C?

87

我怎样才能在CLI(命令行界面)Java应用程序中拦截Ctrl+C(通常会终止进程)?

是否存在跨平台的解决方案(Linux、Solaris、Windows)?

我正在使用ConsolereadLine()方法,但如果需要,我可以使用其他方法从标准输入读取字符。

4个回答

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

这应该能够拦截信号,但仅作为JVM完全关闭之前的中间步骤,因此可能不是您正在寻找的内容。

您需要使用一个SignalHandler (sun.misc.SignalHandler) 来拦截由 Ctrl+C 触发的 SIGINT 信号 (在Unix和Windows上都是如此)。
请参阅此文章 (pdf, 第8页和第9页)。


5
@MartijnCourteaux 那是在五年之后发生的 ;) 我找到了一份关于那个主题的相似资料,并相应地更改了链接。 - VonC
@VonC - 它又挂了。 - Gurwinder Singh
@GurV 哪个链接?我在2014年4月所做的编辑(https://stackoverflow.com/revisions/18adb35b-62a1-4266-b87d-9da49f81d70a/view-source)仍然有效:您仍然可以下载PDF文件。 - VonC

17

我假设您想要优雅地关闭,而不是短路关机过程。如果我的假设正确,那么您应该查看Shutdown Hooks


以前从未听说过关闭挂钩。谢谢! - ivan_ivanovich_ivanoff

8
为了能够处理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应该可以使用,在Windows上我不确定,我记得听说它在某种程度上也与POSIX兼容,但可能会因不同版本而有所不同。


1
第二个链接失效了。它是否更改为Oracle的http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf? - chance
第三个链接也失败了。 - Hugo Zaragoza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接