如何以比上述方法更温和的方式结束所有同名进程killall
?我不想中断进程,但想给它们留出时间正常退出。
也可以看看:
答案1
1. `killall` 已经很好了(SIGTERM)
killall
默认发送SIGTERM
。这是已经这种方法很好,它让应用程序有机会自行清理。“现在就去死吧!”方法是发送一个SIGKILL
信号,这需要将其指定为选项killall
。从GNU C 库:终止信号:
宏:整数 信号终端
[...] 这是正常的做法礼貌地要求程序终止。
2. 系统监视器的“结束进程”同样好用(SIGTERM 也是如此)
您链接到了有关 GNOME 系统监视器的问题。它SIGTERM
也用于其“结束进程”操作(我意识到我与该问题的答案相矛盾)。您可以在源代码中找到它来验证自己:
<item>
<attribute name="label" translatable="yes">_End</attribute>
<attribute name="action">win.send-signal-end</attribute>
<attribute name="accel"><Primary>e</attribute>
<attribute name="target" type="i">15</attribute>
</item>
这里的 15 是信号编号。信号 15 是SIGTERM
。系统监视器SIGTERM
在提出和回答其他问题之前已经使用得很好了。
技术附录(回应评论)
通过查看 Github 上的表示git blame
,我们发现 GNOME 系统监视器源代码中信号的拼写方式发生了以下变化:
383007f22013 年 7 月 24 日 用 GAction 参数替换发送信号的重复代码
0e766b2d2013 年 7 月 18 日 将进程弹出菜单移植到 GAction
97674c792012 年 10 月 3 日 摆脱 ProcData 结构
38c5296c2011 年 7 月 3 日 使源文件中的缩进统一。
这些都没有从到发生改变SIGQUIT
,SIGTERM
并且最后一个是在提出链接问题之前发生的。
答案2
@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 <signal>
。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
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...
(//
在行首使用 a)以删除信号处理程序,然后运行并再次发送信号。您应该能够看到以下不同的输出:
$ ./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()
这种方式的使用被认为是不可移植的 - 但它比其他方法容易得多!
另一个小注脚 - Solariskillall
会尝试终止所有进程。所有进程。如果您以 root 身份运行它,那么您可能会感到惊讶 :)
答案3
“结束一切” 将是killall -s SIGQUIT [process name]
。如果您想要一个奇特的解决方案,请定义alias endall='killall -s SIGQUIT'
。