I was wondering why
i=10
if [ $i -lt 5 ]; then
echo "$i < 5"
elif [ $i -gt 5 ]; then
echo "$i > 5"
elif [ $i -eq 5 ]; then
echo "$i = 5"
fi
Outputs proper result:
10 > 5
Whereas
i=10
[ $i -lt 5 ] && {
echo "$i < 5"
} || [ $i -gt 5 ] && {
echo "$i > 5"
} || [ $i -eq 5 ] && {
echo "$i = 5"
}
behaves an unusual way:
10 > 5
10 = 5
In my opinion, as the interpreter seeks for 1s, it should work like this:
0 && {} || 1 && {} || 0 && {}
0 so the 0 && {} is definitely 0; skip
{}1 means that {} must be checked to define the value of whole
1 && {}
So that the result is 1, but the only {} is executed stays after 1.
However, this all does work as it should when I put ! { instead of {s.
i=10
[ $i -lt 5 ] && ! {
echo "$i < 5"
} || [ $i -gt 5 ] && ! {
echo "$i > 5"
} || [ $i -eq 5 ] && ! {
echo "$i = 5"
}
WHY?! I thought it seeks for 1s so since it finds a 0 in a && it doesn't look at other expressions in the chain!
The {...} does not make a difference, so what you have is equivalent to this:
i=10
[ $i -lt 5 ] &&
echo "$i < 5" ||
[ $i -gt 5 ] &&
echo "$i > 5" ||
[ $i -eq 5 ] &&
echo "$i = 5"
And the way this works is:
[ $i -lt 5 ]: This is false (returns failure), so it jumps to the next ||, which has [ $i -gt 5 ] following it.
[ $i -gt 5 ]: This is true (returns success), so it jumps to the next &&, which has echo "$i > 5" following it.
echo "$i > 5": This returns success, so it jumps to the next &&, which has echo "$i = 5" following it.
echo "$i = 5": This returns success, so it jumps to... wait no, there's a newline. We're done.
&& and || are called short-circuit operators.
EDIT: To stress the point further,
A && B || C
is NOT the same as
if A; then
B
else
C
fi
It's equivalent to
if A; then
if ! B; then
C
fi
else
C
fi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With