When does the system send a SIGTERM to a process?

I'll post this as an answer so that there's some kind of resolution if this turns out to be the issue.

An exit status of 0 means a normal exit from a successful program. An exiting program can choose any integer between 0 and 255 as its exit status. Conventionally, programs use small values. Values 126 and above are used by the shell to report special conditions, so it's best to avoid them.

At the C API level, programs report a 16-bit status¹ that encodes both the program's exit status and the signal that killed it, if any.

In the shell, a command's exit status (saved in $?) conflates the actual exit status of the program and the signal value: if a program is killed by a signal, $? is set to a value greater than 128 (with most shells, this value is 128 plus the signal number; ATT ksh uses 256 + signal number and yash uses 384 + signal number, which avoids the ambiguity, but the other shells haven't followed suit).

In particular, if $? is 0, your program exited normally.

Note that this includes the case of a process that receives SIGTERM, but has a signal handler for it, and eventually exits normally (perhaps as an indirect consequence of the SIGTERM signal, perhaps not).


To answer the question in your title, SIGTERM is never sent automatically by the system. There are a few signals that are sent automatically like SIGHUP when a terminal goes away, SIGSEGV/SIGBUS/SIGILL when a process does things it shouldn't be doing, SIGPIPE when it writes to a broken pipe/socket, etc. And there are a few signals that are sent due to a key press in a terminal, mainly SIGINT for Ctrl+C, SIGQUIT for Ctrl+\ and SIGTSTP for Ctrl+Z, but SIGTERM is not one of those. If a process receives SIGTERM, some other process sent that signal.

¹ roughly speaking


SIGTERM is the signal that is typically used to administratively terminate a process.

That's not a signal that the kernel would send, but that's the signal a process would typically send to terminate (gracefully) another process.

That's the signal that is sent by default by the kill, pkill, killall... commands.

That's the signal that is sent to daemons to stop them (like upon a service some-service stop), or sent by init before shutdown (followed by SIGKILL for those processes that have not managed to terminate in time upon SIGTERM).

Note that SIGTERM is not the signal that is sent upon ^C. The signal sent upon ^C is SIGINT.