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 1
s, 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 1
s 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