简短回答: 发送 SIGTERM
信号,等待 30 秒钟后发送 SIGKILL
信号。也就是说,先发送 SIGTERM
信号,等待一点时间(可能因程序而异,您可能更了解自己的系统,但 5 到 30 秒足够了。在关闭计算机时,您可能会看到它自动等待多达 1 分 30 秒。毕竟为什么要赶急?),然后发送 SIGKILL
信号。
合理回答: 只需要发送 SIGTERM
、SIGINT
和 SIGKILL
信号就足够了。这些信号很可能在发送 SIGKILL
信号之前就已经终止了进程。
长回答: 发送信号:SIGTERM
、SIGINT
、SIGQUIT
、SIGABRT
和 SIGKILL
。
这并不必要,但至少你没有误导进程关于你的信息。所有这些信号都表示你希望进程停止正在进行的工作并退出。
无论您从本说明中选择哪个答案,都要记住这一点!
如果您发送一个意味着其他事情的信号,进程可能会以非常不同的方式处理它(一方面)。另一方面,如果进程没有处理信号,无论您最终发送什么,进程都将退出(当默认操作是终止时,当然)。
因此,您必须像程序员一样思考。您会为 SIGHUP
编写函数处理程序来退出连接到某个程序的程序,还是将其循环以尝试重新连接?这是主要问题!这就是为什么只发送符合你意图的信号很重要。
几乎愚蠢的长回答:
下表包含相关信号和程序未处理它们时的默认操作。
我按照我建议使用的顺序排列了它们(顺便说一句,我建议您使用合理回答,而不是这里的几乎愚蠢的长回答),如果您真的需要尝试它们所有(它会很有趣,可以说表格按照它们可能导致的破坏程度排序,但这并不完全正确)。
带有星号(*)的信号不推荐使用。这些信号的重要之处在于您可能永远不知道它是如何编程的。特别是 SIGUSR
!它可能会引发天启(这是程序员可以随意使用的自由信号!)。但是,如果未处理或在不太可能被处理为终止的情况下它被处理为终止,则程序将终止。
在表格中,具有默认选项以终止并生成核心转储的信号位于 SIGKILL
之前,就在最后一个位置。
Signal Value Action Comment
----------------------------------------------------------------------
SIGTERM 15 Term Termination signal
SIGINT 2 Term Famous CONTROL+C interrupt from keyboard
SIGHUP 1 Term Disconnected terminal or parent died
SIGPIPE 13 Term Broken pipe
SIGALRM(*) 14 Term Timer signal from alarm
SIGUSR2(*) 12 Term User-defined signal 2
SIGUSR1(*) 10 Term User-defined signal 1
SIGQUIT 3 Core CONTRL+\ or quit from keyboard
SIGABRT 6 Core Abort signal from abort(3)
SIGSEGV 11 Core Invalid memory reference
SIGILL 4 Core Illegal Instruction
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
我建议为这个几乎愚蠢的长答案提供以下信号:SIGTERM
、SIGINT
、SIGHUP
、SIGPIPE
、SIGQUIT
、SIGABRT
、SIGKILL
。
最后,这是一个绝对愚蠢又长的回答:
别在家里尝试这个。
SIGTERM
、SIGINT
、SIGHUP
、SIGPIPE
、SIGALRM
、SIGUSR2
、SIGUSR1
、SIGQUIT
、SIGABRT
、SIGSEGV
、SIGILL
、SIGFPE
,如果都不管用,就用SIGKILL
。
应该先尝试SIGUSR2
而不是SIGUSR1
,因为如果程序不处理信号,我们会更好。如果它只处理它们中的一个,那么它更有可能处理SIGUSR1
。
顺便说一下,“杀死”:像其他回答所述,向进程发送SIGKILL
并不是错误的。好吧,想想当你发送一个"shutdown"命令时会发生什么?它只会尝试SIGTERM
和SIGKILL
。为什么这样做呢?如果这个“关机”命令只使用这两个命令,那么你为什么需要任何其他信号呢?
现在回到长答案,这是一个不错的一行代码:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
它在信号之间睡眠30秒钟。为什么你需要一个一行指令呢?;)
另外,建议仅使用来自合理答案的信号15 2 9
进行尝试。
安全性:当您准备好时,请删除第二个echo
。我把它称为我的dry-run
onliners。始终使用它进行测试。
脚本killgracefully
实际上,我对这个问题非常感兴趣,所以我决定创建一个小脚本来完成这个任务。请随意在此处下载(克隆)它:
GitHub链接到Killgracefully repository