Shell : logical ANDs and ORs instead of if-else
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 hasecho "$i > 5"
following it.echo "$i > 5"
: This returns success, so it jumps to the next&&
, which hasecho "$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 Belse Cfi
It's equivalent to
if A; then if ! B; then C fielse Cfi
&&
and ||
are evaluated from left to right. Your command is more or less equivalent to this:
(((( false && { echo 1; true; } ) || true ) && { echo 2; true; } ) || false ) && { echo 3; true; }
false && { echo 1; true; }
doesn't print anything, and evaluates tofalse
false || true
evaluates totrue
true && { echo 2; true; }
prints2
and evaluates totrue
true || false
evaluates totrue
true && { echo 3; true; }
prints3
and evaluates totrue
.
Mystery solved.