Kinder /更温和/更微妙的替代killall(例如“endall”)?

如何以比killall更温和的方式结束具有相同名称的所有进程? 我不想中断这些过程,但要留出时间进行适当的退出。


也可以看看:

如何在Ubuntu中杀死进程?

在系统监视器中,Kill Process和End Process有什么区别?

为什么killall(有时?)需要应用两次?

TL;博士

1.“killall”已经很好了(SIGTERM)

killall默认发送SIGTERM 。 这已经是一种很好的方法,让应用程序有机会自行清理。 “现在已经死了!” 方法是发送SIGKILL信号,该信号需要指定为killall的选项。 来自GNU C库:终止信号 :

宏: int SIGTERM

[…] 礼貌地要求程序终止是正常的方法。


2.系统监视器的“结束进程”同样不错(SIGTERM也是如此)

您链接到有关GNOME系统监视器的问题。 这确实也使用SIGTERM作为其“结束过程”动作(并且我意识到我与该问题的答案相矛盾)。 您可以在源代码中找到它来validation自己:

data / menus.ui :

  _End win.send-signal-end <Primary>e 15  

这里的15是信号编号。 信号15是SIGTERM 。 并且系统监视器在使用SIGTERM之前已经问过并回答了其他问题。


技术附录(回应评论)

通过Gitub表示git blame ,下面是对GNOME系统监视器源代码中如何拼写信号的更改:

383007f2 2013年7月24日更换了用于使用GAction参数发送信号的重复代码
0e766b2d 2013年7月18日端口进程弹出菜单到GAction
97674c79 2012年10月3日摆脱ProcData结构
38c5296c 2011年7月3日在源文件中使缩进统一。

这些都没有从SIGQUIT变为SIGTERM ,最后一个是在问到链接问题之前。

@hvd的答案基本上是正确的。 为了支持更多, init进程将在您关闭计算机时首先将SIGTERM发送到进程,然后在延迟之后发送SIGKILL如果它们尚未退出)。 进程无法处理/忽略SIGKILL

为了提供更多细节,真正的答案是你无法确定程序是否处理它。 SIGTERM是用于礼貌地要求程序退出的最常用信号,但所有信号处理都取决于程序对信号做某事。

换句话说,根据其他答案,如果你有一个由@Jos或@AlexGreg编写的程序,那么他们可能会处理SIGQUIT但可能不是SIGTERM ,因此发送SIGTERM会比SIGQUIT更“软” 。

我写了一些代码,这样你就可以自己玩了。 将下面保存为signal-test.c ,然后编译

 gcc -o signal-test signal-test.c 

然后你可以运行它./signal-test ,看看当你用killall -s 发送不同的信号时会发生什么。

 #include  #include  #include  int flag = 0; void handle_signal(int s) { flag = s; } int main(int argc, char *argv[]) { signal(SIGTERM, handle_signal); signal(SIGQUIT, handle_signal); while(flag == 0){ sleep(1); } printf("flag is %d\n", flag); return flag; } 

就目前而言,代码可以优雅地处理SIGTERM和SIGQUIT。 您可以尝试注释掉行signal(SIG... (在行的开头使用// )删除信号处理程序,然后再次运行并发送信号。您应该能够看到这些不同的输出:

 $ ./signal-test Terminated $ ./signal-test Quit (core dumped) $ ./signal-test flag is 15 $ ./signal-test flag is 3 

取决于您是否处理信号。

您也可以尝试忽略信号:

 signal(SIGTERM, SIG_IGN); 

如果你这样做,那么发送SIGTERM将什么都不做,你将不得不使用SIGKILL来结束这个过程。

man 7 signal更多细节。 请注意,以这种方式使用signal()被认为是不可移植的 – 虽然它比替代方法容易得多!

另一个小脚注 – 在Solaris killall试图杀死所有进程。 他们都是。 如果你以root身份运行它,那么你可能会感到惊讶:)

“结束所有”将是killall -s SIGQUIT [process name] 。 如果你想要一个奇特的解决方案,请定义alias endall='killall -s SIGQUIT'