4

From the bash manual, on the $? variable:

$? Expands to the exit status of the most recently executed foreground pipeline.

I wonder why bash updates the $? variable on pressing Ctrl-C or Ctrl-Z:

$ echo $?
0
$ ^C
$ echo $?
130
$ sleep 10
^Z
[1]+  Stopped                 sleep 10
$ echo $?
148
4

Nothing exits, but the handler for SIGINT (sigint_sighandler()) sets the exit status to 130 (128 + 2, as DopeGhoti's answer explains) anyway:

if (interrupt_immediately)
  {
    interrupt_immediately = 0;
    last_command_exit_value = 128 + sig;
    throw_to_top_level ();
  }

And in throw_to_top_level():

if (interrupt_state)
  {
    if (last_command_exit_value < 128)
    last_command_exit_value = 128 + SIGINT;
    print_newline = 1;
    DELINTERRUPT;
  }
  • Cool. Any clue how come it's set to 148 on Ctrl-Z ? – Eugene Yarmash Dec 28 '15 at 21:34
  • @eugeney Ctrl-Z is SIGTSTP, which is signal 20. (See man 7 signal.) – muru Dec 28 '15 at 21:39
  • Does the process actually exit in this case, or this is again handled by bash somehow? – Eugene Yarmash Dec 28 '15 at 21:46
  • 1
    No, the process doesn't exit (that would be a bug), it is stopped. Again, in this case, the exit status is set by throw_to_level() (see the lines immediately after those which I quoted). – muru Dec 28 '15 at 21:55
5

Because 0 is the exit code for a normal exit state.

Intercepting an Interrupt or Break signal is not a usual exit state, nor is being suspended to the background. The non-zero exit codes tell you this is what is happening so that you can react accordingly in a script if the job it fires off is killed or suspended rather than exiting conventionally with a non-error state.

The interactive shell session, when you press ^C, which throws a SIGINT signal (signal 2), aborts the current interactive command entry, which is a non-normal state for the command entry (i. e. the command prompt) to be in. This causes it to return status 130 (128+2), and give you a new prompt.

More details can be found at http://tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF.

  • I agree, but what process does exit when I just press Ctrl-C in bash? – Eugene Yarmash Dec 28 '15 at 21:08
  • 1
    The interactive shell session, when you press ^C, which throws a SIGINT signal (signal 2), aborts the current interactive command entry, which is a non-normal state for the command entry (i. e. the command prompt) to be in. This causes it to return status 130 (128+2), and give you a new prompt. – DopeGhoti Dec 28 '15 at 21:15
  • 1
    That comment ^ should be part of the answer. – Wildcard Feb 19 '16 at 19:30
  • I shall make it so. – DopeGhoti Feb 20 '16 at 0:00
1

The standard says that the value in $? in case on a received signal is > 128 but the standard does not say how this has to be done.

The Bourne Shell sets $? in case of a singal, it uses 128 + signal number

ksh93 uses 256 + signal number

Note that only signal numbers 1, 2, 3, 6, 9, 14, and 15 are portable.

In other words: SIGTSTP and SIGSTOP use non-portable numbers.

For this reason, the Bourne Shell recently introduced a new portable system, see http://schillix.sourceforge.net/man/man1/bosh.1.html see the ${.sh.termsig} variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.