When is it optional to use ‘$’ character before a variable name in bash?

Viewed 96

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 a loop like this, which works perfectly

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
2 Answers

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 in for ((expr1; expr2; expr3)).
  • let creates an arithmetic context in shells (like bash) that support that ancient, pre-POSIX, nonstandard syntax.
  • In ${array[idx]} or array[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), both value1 and value2 are parsed as arithmetic. This is also true for -eq, -ne, -lt, -gt and -ge.
  • In ${string:start:len}, both start and len are arithmetic contexts.
  • When declare -i variable has declared a variable to have a numeric type, and variable=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).

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).

Related