# Exit Status - exit code - return status ## Purpose The exit status is a numeric value that is returned by a program to the calling program or shell. In C programs, this is represented by the return value of the `main()` function or the value you give to `exit(3)`. The only part of the number that matters are the least significant 8 bits, which means there are only values from 0 to 255. In the shell, every operation generates an exit status (return status), even if no program is called. An example for such an operation is a redirection. The parameter to the - `exit` (exit the shell/script) - `return` (return from a function) builtin commands serve the purpose of giving the exit status to the calling component. This - and only this - makes it possible to determinate the success or failure of an operation. For scripting, always set exit codes. ## Values The code is a number between 0 and 255, where the part from 126 to 255 is reserved to be used by the Bash shell directly or for special purposes, like reporting a termination by a signal: |Code|Description| |----|-----------| |0|success| |1-255|failure (in general)| |126|the requested command (file) can't be executed (but was found)| |127|command (file) not found| |128|according to ABS it's used to report an invalid argument to the exit builtin, but I wasn't able to verify that in the source code of Bash (see code 255)| |128+N|the shell was terminated by the signal N (also used like this by various other programs)| |255|wrong argument to the exit builtin (see code 128)| The lower codes 0 to 125 are not reserved and may be used for whatever the program likes to report. A value of **0 means successful** termination, a value **not 0 means unsuccessful** termination. This behavior (== 0, != 0) is also what Bash reacts on in some code flow control statements like `if` or `while`. ## Portability Tables of shell behavior involving non-portable side-effects or common bugs with exit statuses. Note heirloom doesn't support pipeline negation (`! pipeline`). ### Misc |test|bash 4.2.45|bash (POSIX)|zsh 5.0.2 (emulate ksh)|ksh93 93v- 2013-03-18|mksh R44 2013/02/24|posh 0.11|dash 0.5.7.3|busybox 1.2.1|heirloom 050706| |--|--|--|--|--|--|--|--|--|--| |
:; : \`false\` \`echo $? >&2\`|1|1|1|1|0|0|0|0|1| |
false; eval; echo $?|0|0|0|0|0|1|0|1|0| |
x=\`false\` eval echo $?|1|1|1|1|0|0|0|0|1| |
eval echo \$? <&0\`false\`|1|1|1|1|0|0|0|0|1| |
while :; do ! break; done; echo $?|1|1|1|1|0|0|1|1|-| |
false; :| echo $?
(exit 2); for x in "\`exit 3\`"; do echo $?; done|3|3|3|3|2|2|0|0|3| ### functions Measuring side-effects during the function call, during return, and transparency of the return builtin. |test|bash|bash
f() { echo $?; }; :; f \`false\`|1|1|1|1|0|0|0|0|1| |
f() { return; }; false; f; echo $?|1|1|1|0|1|1|1|1|1| |
f() { return $?; }; false; f; echo $?|1|1|1|1|1|1|1|1|1| |
f() { ! return; }; f; echo $?|0|0|1|0|0|0|1|1|-| |
f() { ! return; }; false; f; echo $?|1|1|0|0|1|1|0|0|-| |
f() { return; }; x=\`false\` f; echo $?|1|1|1|1|0|0|0|0|0| |
f() { return; }; f <&0\`false\`; echo $?|1|1|1|1|0|0|0|0|1| |
f() { x=\`false\` return; }; f; echo $?|1|1|1|0|0|0|0|0|1| |
f() { return <&0\`false\`; }; f; echo $?|1|1|1|0|0|0|0|0|1| |
f() { x=\`false\` return <&0\`false\`; }; f; echo $?|1|1|1|1|0|0|0|0|1| ### case..esac Statuses measured within the command and after, with matching and non-matching patterns. |test|bash|bash
(exit 2); case x in x) echo $?;; esac|2|2|0|2|2|2|0|0|2| |
(exit 2); case \`exit 3\`x in x) echo $?;; esac|3|3|0|3|2|2|0|0|3| |
(exit 2); case x in \`exit 4\`x) echo $?;; esac|4|4|4|4|2|2|0|0|4| |
(exit 2); case \`exit 3\`x in \`exit 4\`x) echo $?;; esac|4|4|4|4|2|2|0|0|4| |
(exit 2); case x in x);; esac; echo $?|0|0|0|0|0|0|0|0|2| |
(exit 2); case x in "");; esac; echo $?|0|0|0|0|0|0|0|0|2| |
(exit 2); case \`exit 3\`x in x);; esac; echo $?|0|0|0|3|0|0|0|0|3| |
(exit 2); case \`exit 3\`x in "");; esac; echo $?|0|0|0|3|0|0|0|0|3| |
(exit 2); case x in \`exit 4\`x);; esac; echo $?|0|0|0|4|0|0|0|0|4| |
(exit 2); case x in \`exit 4\`);; esac; echo $?|0|0|4|4|0|0|0|0|4| |
(exit 2); case \`exit 3\`x in \`exit 4\`);; esac; echo $?|0|0|4|4|0|0|0|0|4| |
(exit 2); case \`exit 3\`x in \`exit 4\`x);; esac; echo $?|0|0|0|4|0|0|0|0|4|