First of all I'm not a Bash pro. I discovered few months ago that if I use both the &&
and ||
short circuit operators in sequence with curly braces, then in case the first statement exits with a truthful value, if the last statement in the true block exits non-zero, then the fail block will be executed too. Like this:
returnNumber 0 && {
echo 'OK'
returnNumber 1
} || {
echo 'NG'
}
Will output:
OK
NG
So, I looked for the easiest solution for this, and came up with this:
returnNumber 0 && {
echo 'OK'
returnNumber 1
:
} || {
echo 'NG'
}
I know, it is easy to leave out the colon builtin, but is it a proper way for a workaround?
This is actually a very common Bash pitfall. It is not a bug.
returnNumber 0
evaluates to true, so the second block (joined by logical and &&
) is evaluated as well to make sure the result of first && second
is still true.
The second block outputs OK
but evaluates to false, so now the result of first && second
is false. This means that the third portion (joined by logical or ||
) must be evaluated as well, causing NG
to be displayed as well.
Instead of relying on &&
and ||
, you should be using if
statements:
if returnNumber 0; then
echo 'OK'
returnNumber 1
else
echo 'NG'
fi
tl;dr: Never use x && y || z
when y
can return a non-zero exit status.