比较bash
,ash
和dash
, 只能bash
通过以下方式终止SIGTERM
kill -TERM <pid>
对于ash
和bash
,我需要SIGHUP
或SIGKILL
kill -HUP <pid>
kill -KILL <pid>
这背后的原因是什么?此外,该行为似乎与系统相关:
bash
SIGTERM
在 Ubuntu 14.04 Trusty、Ubuntu 16.04 Xenial、Ubuntu 18.04 Bionic、Ubuntu 19.10 Eoan、Ubuntu 20.04 Focal、Debian 8 Jessie、Debian 9 Stretch、Debian 10 Buster、CentOS 8 上终止bash
是不是SIGTERM
在 CentOS 6、CentOS 7 上终止
答案1
仅当 bash 使用readline
行编辑库并且bash
等待用户输入时才会发生这种情况。
如果运行,Abash --noediting
不会被杀死SIGTERM
,也不会杀死自己。bash
kill -TERM $$
发生这种情况是因为readline()
bash 用于获取用户输入的函数将安装自己的信号处理程序SIGTERM
,并在返回之前恢复原始信号处理。如果在等待用户输入SIGTERM
时发生,将返回。readline
readline()
NULL
readline()
调用( )的 bash 函数yy_readline_get()
会将NULL
return 解释为EOF
,导致 shell 退出。场景与此非常相似回答。
SIGTERM
这意味着交互式 bash 也可以通过设置来生存IGNOREEOF
;-):
$ bash
$ IGNOREEOF=10
$ echo $$
11096
<kill -TERM 11096 from another terminal>
$ Use "exit" to leave the shell.
<kill -TERM 11096 from another terminal>
$ Use "exit" to leave the shell.
...
<the 10th will get it>
$ exit
$
答案2
这对我来说是出乎意料的,但进行了几次构建后发现它可以在 git 的 bash 最新代码上重现,但不能在 bash 4.0 上重现。因此,这git bisect
有助于确定以下提交是负责的:
% git bisect good
ac50fbac377e32b98d2de396f016ea81e8ee9961 is the first bad commit
commit ac50fbac377e32b98d2de396f016ea81e8ee9961
Author: Chet Ramey <[email protected]>
Date: Wed Feb 26 09:36:43 2014 -0500
Bash-4.3 distribution sources and documentation
Bash 的各个 git 提交往往相当大,范围也不是非常严格,但是花几分钟浏览一下该提交会发现 readline 处理 SIGTERM 的方式发生了许多变化,包括 SIGTERM 应该绕过的新 rl_signal_event_hook 以及大量新的我们检查 SIGTERM 并调用 的地方termsig_handler
。
这些更改的一部分与更改日志中的新条目相匹配:
Readline 在读取输入时收到信号后调用应用程序设置的事件挂钩 (rl_signal_event_hook)(read 返回 -1/EINTR,但 readline 不会立即处理该信号)以允许应用程序处理或以其他方式记录该信号。目前不调用 SIGHUP 或 SIGTERM。
从这条消息来看,我认为行为的改变可能不是故意的。
我将把这个帖子转发到 bug-bash 邮件列表,希望能弄清楚这是否是故意的。