2

Comparing bash, ash and dash, only bash can be terminated by SIGTERM

kill -TERM <pid>

For ash and bash, I need SIGHUP or SIGKILL

kill -HUP <pid>
kill -KILL <pid>

What's the reasoning behind this? Furthermore, the behavior seems to be system-dependent:

  • bash is terminated by SIGTERM on 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 is not terminated by SIGTERM on CentOS 6, CentOS 7
finefoot
  • 3,060
  • 1
    https://www.gnu.org/software/bash/manual/bash.html#Signals: "When Bash is interactive, in the absence of any traps, it ignores SIGTERM (so that ‘kill 0’ does not kill an interactive shell) ..." So did you kill an interactive shell or a script? – muru Mar 04 '20 at 16:47
  • If I simply run bash in my terminal emulator, isn't that an interactive session? That's what I killed by running kill <pid> (inside another terminal emulator). – finefoot Mar 04 '20 at 16:52
  • 1
    Shells are generally made to terminate when receiving the HUP ("hang-up") signal, not TERM. – Kusalananda Mar 04 '20 at 16:57
  • 3
    I could witness OP's behaviour on Debian9 and Debian10's or CentOS8's bash, going against the relevant information in the man page. Works as expected (not killed) on CentOS7 – A.B Mar 04 '20 at 17:08
  • 1
    @A.B. It has rather to do with the bash version than with the distro it runs on. Also, it has to do with readline installing its own signal handlers -- bash --noediting will not be killed by an SIGTERM. Nor will bash kill itself by running kill -TERM $$. See here for something similar. –  Mar 04 '20 at 17:33

2 Answers2

4

This only happens when bash is using the readline line editing library, and only when bash is waiting for input from the user.

A bash --noediting will not be killed by SIGTERM, nor will bash kill itself if running kill -TERM $$.

This happens because the readline() function used by bash to get input from the user, will install its own signal handler for SIGTERM, and restore the original signal disposition before returning. If a SIGTERM happens while readline is waiting for input from the user, readline() will return NULL.

The bash function which calls readline() (yy_readline_get()) will interpret a NULL return as EOF, causing the shell to exit. The scenario is quite similar to that from this answer.

This means that an interactive bash could be also made to survive a SIGTERM by setting 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
$
3

This was unexpected to me, but doing a couple of builds revealed it was reproducible on bash's latest code from git, but not bash 4.0. As such git bisect was helpful in pinpointing the following commit as being responsible:

% git bisect good                     
ac50fbac377e32b98d2de396f016ea81e8ee9961 is the first bad commit
commit ac50fbac377e32b98d2de396f016ea81e8ee9961
Author: Chet Ramey <chet.ramey@case.edu>
Date:   Wed Feb 26 09:36:43 2014 -0500

    Bash-4.3 distribution sources and documentation

Bash's individual git commits tend to be fairly large and not super tightly scoped, but spending a few minutes going through that commit shows a number of changes to how readline handles SIGTERM, including a new rl_signal_event_hook which SIGTERM is supposed to bypass, and plenty of new places that we check for SIGTERM and call termsig_handler.

Part of those changes matches up with this new entry in in the changelog:

Readline calls an application-set event hook (rl_signal_event_hook) after it gets a signal while reading input (read returns -1/EINTR but readline does not handle the signal immediately) to allow the application to handle or otherwise note it. Not currently called for SIGHUP or SIGTERM.

Judging by this message, I believe the change in behaviour may not be intentional.

I'm going to forward this thread to the bug-bash mailing list in the hopes of getting to the bottom of whether this was intentional or not.

Chris Down
  • 125,559
  • 25
  • 270
  • 266
  • For future reference, this is the thread on the bug-bash list: https://lists.gnu.org/archive/html/bug-bash/2020-03/msg00006.html – Kusalananda May 24 '20 at 22:12