Reputation: 25
I am using short-circuit evaluation (with &&
and ||
) in a bash function,
and I don't understand the behavior I'm seeing. I want the function to return
if the first number is not greater than the second:
[[ 5 > 2 ]] && echo true || echo false && return
# ^ ^ ^
# true so do this not this && this
[[ 5 > 8 ]] && echo true || echo false && return
# ^ ^ ^
# false so don't do this do this && this
but the function returns in either case.
Why does the return
command execute regardless of the first command's status?
Instead of return
I have tried break
,
but it doesn't work due to not being within a loop.
Why does return
seem to execute in both these cases?
How else can I end a running function?
Upvotes: 1
Views: 89
Reputation: 908
stmt1 && stmt2 || stmt3 && stmt4
is evaluated as
( ( stmt1 && stmt2 ) || stmt3 ) && stmt4
i.e., left to right.
So the logic is
Execute stmt1 If it succeeds, then execute stmt2 endif If stmt1 succeeds and stmt2 succeeds, then (do nothing here) else # i.e., if stmt1 fails, OR stmt1 succeeds and then stmt2 fails execute stmt3 endif If stmt1 succeeds and stmt2 succeeds, OR stmt3 succeeds, then execute stmt4 endif
Since stmt2
and stmt3
are both echo
statements, they both always succeed,
and so stmt4
(the return
statement)
is always executed.
I suspect you were expecting
( stmt1 && stmt2 ) || ( stmt3 && stmt4 )
and you can get that behavior (in general) by typing parentheses, just like that:
( [[ 5 > N ]] && echo true ) || ( echo false && return ) # No, don’t do this
or braces:
{ [[ 5 > N ]] && echo true; } || { echo false && return; }
Note that you must have whitespace after a {
and a semicolon before a }
.
Note also that, with parentheses, the commands run in subshells,
whereas with braces, they don’t (they run in the main shell context).
In your specific code example, you must use braces
(at least for the part after the ||
),
because return
doesn’t have any effect if it’s run in a subshell.
Upvotes: 4
Reputation: 780974
Use if
instead of logical operators.
if [[ 5 > 8 ]]
then echo true
else
echo false
return
fi
See precedence of the shell logical operators for an explanation of how the operators combine.
Upvotes: 2