58

I am confused about the meaning of the exit code in the end of a bash script: I know that exit code 0 means that it finished successfully, and that there are many more exit codes numbers (127 if I'm not mistaken?)

My question is about when seeing exit code 0 at the end of a script, does it force the exit code as 0 even if the script failed or does it have another meaning?

6
  • 2
    If a script ends with exit 0, it will exit with the exit code of 0 regardless of what happens within the script.
    – Hatclock
    Commented Sep 6, 2016 at 14:26
  • 1
    @Hatclock why didn't you post your answer a full pledged answer ? as a comment I cant mark it, and I don't think you get fake internet points for answering (right?) Just a thought... (kudos for the fast reply)
    – soBusted
    Commented Sep 6, 2016 at 14:46
  • 3
    I'm at a train station on my phone, I don't really like typing too much on my phone. ilkkachu seems to have a good answer though!
    – Hatclock
    Commented Sep 6, 2016 at 14:55
  • 2
    @Hatclock No, not at all. If a script ends with exit 0, it will exit with the code 0 only if that last instruction was executed. The only impact of exit 0 at the end of the script is to return 0 instead of the status from the previous instruction. Commented Sep 6, 2016 at 22:08
  • 1
    @Gilles That was more of an ambiguously worded reply on my part. If a script runs exit 0 at any point it will return exit code 0 regardless of what has happened prior to that.
    – Hatclock
    Commented Sep 7, 2016 at 9:26

3 Answers 3

52

The builtin command exit exits the shell (from Bash's reference):

exit [n]
Exit the shell, returning a status of n to the shell’s parent. If n is omitted, the exit status is that of the last command executed. Any trap on EXIT is executed before the shell terminates.

Running to the end of file also exits, returning the return code of the last command, so yes, a final exit 0 will make the script exit with successful status regardless of the exit status of the previous commands. (That is, assuming the script reaches the final exit.) At the end of a script you could also use true or : to get an exit code of zero.

Of course more often you'd use exit from inside an if to end the script in the middle.

These should print a 1 ($? contains the exit code returned by the previous command):

sh -c "false" ; echo $?
sh -c "false; exit" ; echo $?

While this should print a 0:

sh -c "false; exit 0" ; echo $?

I'm not sure if the concept of the script "failing" when executing an exit makes sense, as it's quite possible to some commands ran by the script to fail, but the script itself to succeed. It's up to the author of the script to decide what is a success and what isn't.

Also, the standard range for exit codes is 0..255. Codes above 127 are used by the shell to indicate a process terminated by a signal, but they can be returned in the usual way. The wait system call actually returns a wider value, with the rest containing status bits set by the operating system.

4
  • Cool, I didn't know about the 8 bits exit codes numbering. Thanks!
    – soBusted
    Commented Sep 6, 2016 at 15:30
  • 1
    Note that when a process is killed, it does not exit with an exit code > 127. It's just that some shells set $? to 128+signum in that case. See Default exit code when process is terminated? for details. Commented Sep 6, 2016 at 16:13
  • exit 0 will only return 0, if the exit is executed. (it could exit by a different route). Commented Aug 16, 2018 at 14:34
  • 1
    (the exit code isn't usually clamped to the 0..255 range, most shells just take the low 8 bits, so you get modulo 256. E.g. (exit 300); echo $? prints 44)
    – ilkkachu
    Commented Sep 29, 2023 at 6:30
37

0 means success, positive integers mean failure. There are 255 different error codes, but values 126 and above are reserved to indicate that a program couldn't start (126 or 127) or was killed by a signal (129 and above). See Default exit code when process is terminated? and What return/exit values can I use in bash functions/scripts? for more information.

The exit status of a shell script is the exit status of the last command that the script executed. So for example

#!/bin/sh
somecommand

returns the exit status of somecommand, whereas

#!/bin/sh
somecommand
exit 0

returns 0 regardless of what somecommand returned. This second script could also be written

#!/bin/sh
somecommand
true

Putting exit 0 at the end of a script doesn't necessarily cause it to return 0. This only makes it return 0 when the end of the script is reached. For example, the following script always returns 3:

#!/bin/sh
exit 3
exit 0

The following script also always returns an error code, in addition to displaying a message about a syntax error:

#!/bin/sh
}
exit 0

The following script returns either 1 or 0 depending on its first argument:

#!/bin/sh
if [ "$1" = "foo" ]; then
  exit 1
fi
exit 0

The following script returns the status of somecommand, since set -e causes the script to exit if somecommand fails:

#!/bin/sh
set -e
somecommand
exit 0
2
  • for your last set -e example, if I have command1 and command2, and command1 exits with 8, does it cause the script to exit with 8?
    – bilogic
    Commented Apr 29 at 9:56
  • @bilogic Yes. The script exits with the status of the last command that it runs. With set -e, that's the command whose failure caused the script to exit. Commented Apr 29 at 10:34
0

The exit status (also sometimes called return code or exit value or some variant of these) is a numeric value of last executed program in the script. Explicit exit 0 simply stops the script (technically a side-effect) and sets exit status of last executed command to given value (0 in this example).

By tradition, exit status 0 is considered successful and any other value is application defined. For example, man grep tells following:

EXIT STATUS
Normally the exit status is 0 if a line is selected, 1 if no lines were selected, and 2 if an error occurred. However, if the -q or --quiet or --silent is used and a line is selected, the exit status is 0 even if an error occurred.

If you want to have successful exit status you can simply end the script with any successful command like true. This might be preferable to writing exit 0 for script future maintenance: if somebody later adds new lines to the script, those will be ignored if exit 0 is left in the middle but true in the middle doesn't prevent later lines from being executed.

Typically shells interpret exit status as 8 bit number and values between 128–255 are shell defined and may match 128+N for signal number N for script being interrupted by signal N but you shouldn't count on this.

The Linux kernel supports exit status values outside 0-255 range that POSIX compatible shells use. If the program exits with value outside this range, the shell reported status will be true value modulo 256 (which is identical to running C code raw_exit_code && 0xFF). The 8-bit exit status is also used by many user mode APIs as explained in detail here: https://unix.stackexchange.com/a/418802/20336.

2
  • Re. that "If you end the script with something that is successful (e.g. true) it will quit with exit status that matches the exit status of that command." part, woudn't that be true even for something that's not successful (in the sense of returning a falsy exit status)? Second, are you sure the Linux kernel supports exit status values outside 0-255? Because e.g. the _exit() man page explicitly says "The value status & 0xFF is returned to the parent process as the process's exit status", etc. (Some other systems might support the wider range of values, yes)
    – ilkkachu
    Commented Jun 20 at 12:51
  • I'll improve the wording to be more clear. As explained here, the kernel supports values greater than 8-bit but the user mode API truncates the status to 8-bit in many cases to be compatible with historical behavior: unix.stackexchange.com/a/418802/20336 Commented Jun 20 at 13:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .