Could someone please explain why this works, specifically the fact that I am not using ‘$’ character before the names of the variables inside the if statement? I have searched the Bash Reference Manual, but could not find an explanation.
#!/usr/bin/env bash
one="$1"
two="$2"
three="$3"
four="$4"
if [[ one -le two ]] && [[ three -ge four ]]; then
echo "TRUE: $one <= $two && $three >= $four"
else
echo "FALSE: $one <= $two && $three >= $four"
fi
I have also tested it with for x1 in {1..3}; do for x2 in {1..3}; do for x3 in {1..3}; do for x4 in {1..3}; do ./test $x1 $x2 $x3 $x4; done; done; done; done |sort
and it works perfectly.
CodePudding user response:
In the description of Bash Conditional Expressions the description of the arithmetic comparison operators (-lt
, -gt
, etc.) says:
When used with the [[ command, Arg1 and Arg2 are evaluated as arithmetic expressions (see Shell Arithmetic).
And when you follow that link it says:
Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax.
And the description of Arithmetic Expansion -- $((expression))
says:
All tokens in the expression undergo parameter and variable expansion, command substitution, and quote removal. ... The evaluation is performed according to the rules listed below (see Shell Arithmetic).
CodePudding user response:
Dollar signs are optional inside an arithmetic context. This is any context where a value is going to be interpreted as a number.
$(( ... ))
creates an arithmetic context in all POSIX shells(( ... ))
creates an arithmetic context in bash, including infor ((expr1; expr2; expr3))
.let
creates an arithmetic context in shells (like bash) that support that ancient, pre-POSIX, nonstandard syntax.- In
${array[idx]}
orarray[idx]=value
,idx
is evaluated as arithmetic as long as the array has not been declared to be associative. - In
[[ value1 -le value2 ]]
, because-le
is an arithmetic operator (it only does numeric comparisons, not string comparisons), bothvalue1
andvalue2
are parsed as arithmetic. This is also true for-eq
,-ne
,-lt
,-gt
and-ge
. - In
${string:start:len}
, bothstart
andlen
are arithmetic contexts. - When
declare -i variable
has declared a variable to have a numeric type, andvariable=value
is subsequently run,value
is an arithmetic context.
Note that this is not true for arithmetic comparisons inside test
or [
commands; test
(whether or not called under the name [
) acts like a regular shell command rather than special syntax (despite having a built-in implementation as a performance optimization).