First, exit 130
is not an abnormal exit. It is a normal exit, with exit status 130. As can be seen from man 3 wait
(POSIX):
If the information pointed to by stat_loc was stored by a call to
waitpid() that specified the WUNTRACED and WCONTINUED flags,
exactly one of the macros WIFEXITED(*stat_loc), WIFSIGNALED(*stat_loc),
WIFSTOPPED(*stat_loc), and WIFCONTINUED(*stat_loc) shall evaluate to
a non-zero value.
WIFEXITED
checks normal exit, and WIFSIGNALLED
is termination due to an uncaught signal. Since these are mutually exclusive, an exit 130
is normal.
That the exit status is 130 when a process dies by SIGINT is because bash sets it to be 130 outside of the process because it detected an exit due to SIGINT: Why does bash set $? (exit status) to non-zero on Ctrl-C or Ctrl-Z?
Second, a process that handles SIGINT and then dies should kill itself with SIGINT. Greg's wiki (an excellent resource for shell stuff) has a note on this:
If you choose to set up a handler for SIGINT (rather than using the
EXIT trap), you should be aware that a process that exits in response
to SIGINT should kill itself with SIGINT rather than simply
exiting, to avoid causing problems for its caller. Thus:
trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT
Now, if you changed the exit 130
to:
trap - INT
kill -INT $$
You'd see the expected behaviour.
Assignment can fail if the right hand expression fails to evaluate
eg
$ x=HELLO
$ x=$((1/0))
bash: 1/0: division by 0 (error token is "0")
$ echo $?
1
In this scenario the value of $x
is left unchanged:
$ echo $x
HELLO
Best Answer
When you press Ctrl+C on the command line, nothing exits, but the handler for
SIGINT
(sigint_sighandler()
) sets the exit status to 130 (128 + 2, as DopeGhoti's answer explains) anyway:And in
throw_to_top_level()
:When you press Ctrl+C to kill a background process, the shell observes that the process has died and also sets the exit status
$?
to 128 plus the signal number.When you press Ctrl+Z to suspend a background process, the shell observes that something has happened to the process: it hasn't died, but the information is reported through the same system call (
wait
and friends). Here as well, the shell sets the exit status$?
to 128 plus the signal number, which is 148 (SIGTSTP = 20).