Why Bash Ignores SIGTERM – Understanding Signal Handling

bashsignals

Sometimes when I want to logout quickly I do kill -15 -1. I've noticed that bash is ignoring SIGTERM.

I wonder what's the rationale for such bash behavior?

It's not very UNIX'y to ignore SIGTERM without a good reason, isn't it?

UPDATE:

same (no)effect for all:

$ kill -TERM $$
$ type kill
kill is a shell builtin
$ command kill -TERM $$
$ /bin/kill -TERM $$

UPDATE2:

From man bash:

When bash is interactive, in the absence of any traps, it ignores
SIGTERM

So it's done on purpose. But why?

Best Answer

First, this isn't specific to bash. ATT ksh, dash and zsh behave the same way: they ignore SIGTERM and SIGQUIT during command line edition; as for mksh, it also doesn't quit but treats them like SIGINT.

Both the ksh manual and the bash manual justify ignoring SIGTERM in these terms:

so that kill 0 does not kill an interactive shell

kill 0 kills all processes in the process group that the shell is in¹. In a nutshell, the process group consists of all the processes running in the foreground on a terminal, or all the processes in a background or suspended job.

More precisely, this is what happens in modern shells with job control. In such shells, kill 0 wouldn't be useful, as the shell would be in a process group of its own. Older shells (or modern shells after set +m) did not create process groups for background commands. So you could use the command kill 0 to kill all background commands without getting logged out.² Thus the kill 0 rationale looks like an old one which is no longer justified nowadays but kept for backward compatibility.

However there are other similar situations where making the shell immune is useful. Consider the case where you have processes hogging a terminal and you want to kill them without getting logged out. Many systems have a tool like pkill which let you kill the processes running on a terminal. You can run pkill -t $TTY or pkill -QUIT -t $TTY to kill all processes that are running on the current terminal, except the shell which ignores the signal.

A shell normally goes away either when the user exits it (with a command like exit or logout), or when its terminal signals the end of the input (the user can cause this by pressing Ctrl+D) or goes away altogether. In this last case, the shell receives the signal SIGHUP, and it doesn't ignore that one.

For your use case of logging out of an X session, kill -15 -1 will do it, since it kills the terminal emulator which causes the shell to receive SIGHUP. It's in fact enough to kill the X server, but that requires finding its process ID. If you want the same command to work on a text session, you can use kill -15 -1; exit. That's quite a dangerous command to have at your fingertips anyway.

¹ This doesn't seem to be mentioned in shell manuals as a rule; it's a feature of the underlying system call. It is mentioned explicitly in the POSIX specification.
² Nowadays, to do that, run jobs -l to see a list of jobs with their process group ID, then kill -123 -456 … to kill the process groups.

Related Question