In most programming languages that are able to treat integers as booleans, a non-zero value (not just 1) is "true" and the value zero is "false".
For example in C:
int a = some_function();
if (a) {
puts("some_function returned a non-zero value");
}
... and similarly in Python (but obviously with different syntax).
In the shell, this is less useful as utilities would want to signal either success or failure to do whatever it is that they would like to do, and a failure may need to be distinguished with more detail than just "I failed".
This means that there is a single exit status, zero, that means "success", "everything went ok", or "I did what I was supposed to do", and that any other exit value should be taken as "failure". Some utilities use more than one non-zero exit status to further let the user know what went wrong (see e.g. "EXIT CODES/VALUES" in the manuals for rsync
and curl
).
Furthermore, if a utility is killed by a signal, the exit status of the utility will be 128 plus the signal number (see kill -l
on your system).
From the introductory text on "Shell & Utilities" in the POSIX standard (talking about various sections of a manual, a better reference is welcomed):
The EXIT STATUS
section describes the values the utility shall return to the calling program, or shell, and the conditions that cause these values to be returned. Usually, utilities return zero for successful completion and values greater than zero for various error conditions. If specific numeric values are listed in this section, the system shall use those values for the errors described. In some cases, status values are listed more loosely, such as >0. A strictly conforming application shall not rely on any specific value in the range shown and shall be prepared to receive any value in the range.
For example, a utility may list zero as a successful return, 1 as a failure for a specific reason, and >1 as "an error occurred". In this case, unspecified conditions may cause a 2 or 3, or other value, to be returned. A conforming application should be written so that it tests for successful exit status values (zero in this case), rather than relying upon the single specific error value listed in this volume of POSIX.1-2008. In that way, it has maximum portability, even on implementations with extensions.
Note that library functions sometimes return non-zero (and therefore "true") values for error conditions. For example, the standard C functions fgetc()
and fputc()
returns EOF
(usually -1) on error, which is a "true" value since it is non-zero.
So there is a subtle difference between the discussion about how integers are interpreted as booleans in programming languages and in the shell, and how error conditions are reported (these are two related topics).
(( 0 ))
is false in bash but(( 1 ))
is true, so it depends on context. – jordanm Mar 08 '18 at 17:21