You are confusing two different things:
Integers as used as boolean.
A boolean is a response to a question: "Is this variable's value the same as this other variable's value?" The answer is a false or a true. These could be encoded as 0 or 1.
Integers as used as exit-status.
An exit-status is a statement of fact: "The utility terminated after successfully doing what it was asked to do.", "The utility encountered a particular error condition and failed." The exit-status could be encoded as any integer between 0 and 127, where zero signifies success or no error.
These are similar, but only because both use integers as a way of encoding true and false (booleans), or successful and unsuccessful (exit status). Other things that use integers are the number of centimeters an athlete can jump, and the ranking associated with that athlete based on that jump, but we rarely confuse these.
In the C language, if
statements act directly on the result of the arithmetic evaluation of the given expression. Since the shell has always been geared towards execution of programs and handling of job pipelines etc., an if
statement in the shell is made for determining whether a utility successfully ran or not. This involves examining the exit-status of the utility that it ran.
An exit-status is zero if the utility finished successfully. You get a boolean when you ask "Is the exit-status zero?", which is what the if
statement in the shell is doing (if utility; then echo ok; else not ok; fi
). If the utility wasn't successful, you'll get a false back from that test, and you may then start looking at the exit-status and the utility's diagnostic output to try to figure out what went wrong.
The exit-status may encode the specific reason the utility terminated unsuccessfully, a bit like library functions and system calls in C often sets an "errno
status code" that encode similar information to the caller (see man errno
and, as an example, the RETURN VALUE
and ERRORS
sections of stat(2)
with man 2 stat
).
The false
utility does nothing, unsuccessfully. You can see that it fails because it sets a non-zero exit status:
$ false; echo "$?"
1
This 1
is not a boolean. It's a non-zero exit-status signifying failure.
If you want to do boolean logic in the shell, use $(( ... ))
to evaluate your expression, and the test
utility for comparing:
if [ "$(( a == 12 ))" -ne 0 ]; then
echo 'a is 12'
fi
In this example, the value $a
is compared as an integer against 12. If $a
is 12, the arithmetic expansion would expand to 1
, otherwise to 0
. These are boolean values.
The exit-status of [ "$(( a == 12 ))" -ne 0 ]
would be zero if $a
was 12, causing the echo
to be executed, or non-zero if $a
wasn't 12, causing the echo
to be skipped.
For utilities with more interesting exit-statuses than just 0 and 1, see e.g. the curl
manual (the EXIT CODES
section towards the end), and the rsync
manual (the EXIT VALUES
section towards the end).