I have this code:
fruit=apple
flag=0
[[ $fruit = "apple" && ((flag == 0)) ]] && echo "1"
[[ $fruit = "apple" && (($flag == 0)) ]] && echo "2"
[[ $fruit = "apple" && ((! flag)) ]] && echo "3"
[[ $fruit = "apple" && ((! $flag)) ]] && echo "4"
All of them are expected to echo something. However, only the second statement works properly:
[[ $fruit = "apple" && (($flag == 0)) ]] && echo "2"
Why is this? Won't arithmetic expressions work properly inside [[ ]]
?
The ==
works the same as =
- it is a string comparision.
The ( )
inside [[
]]
is used to nest expressions. Ex. [[ a = a && (b = b || c = d) ]]
A non empty string is true. So [[ some_string ]]
or [[ "some other string" ]]
returns true. [[ "" ]]
or [[ '' ]]
returns false.
The !
is negation.
[[ $fruit = "apple" && ((flag == 0)) ]]
First the expansion of $fruit
happens. So it becomes: [[ "apple" = "apple" && ( ( "flag" == "0" ) ) ]]
. The ( )
are just braces, this is not arithemtic expansion. The string "apple"
is equal to "apple"
, but the string "flag"
is not equal to string "0"
, so it always returns with false.
[[ $fruit = "apple" && (($flag == 0)) ]]
Because $flag
is expanded, the [[
sees: [[ "apple" = "apple" && ((0 == 0)) ]]
. So the comparision happens to work, however ==
is doing string comparision.
[[ $fruit = "apple" && ((! flag)) ]]
The flag
is a nonempty string, so it evaulates to true. The ! flag
evaulates to false.
[[ $fruit = "apple" && ((! $flag)) ]]
First $flag
is expanded to 0
. As 0
is a nonempty string, it evaluates to true. The ! 0
evaluates to false. The ((! 0))
is false, so the whole expression returns nonzero.
Won't arithmetic expressions work properly inside [[ ]]?
No, arithmetic expressions will not work inside [[
]]
the same way [[ echo 1 ]]
does not work. The echo 1 ]]
are arguments of [[
builtin, not a standalone command. The same way [[ (( 0 )) ]]
the (( 0 )) ]]
are interpreted as arguments to [[
.