user7662982
user7662982

Reputation:

When do I need to use a $ to refer to a variable in Bash?

For example, in my code sometime I do

$var

and sometimes I just do

var

Here is a more concrete example:

upstream() {
    push server_shared_shortname
    ssh $server_shared -t "cd  ~/public_html; git pull -q ~/root.git master"
}

Upvotes: 1

Views: 346

Answers (2)

mklement0
mklement0

Reputation: 440337

  • On assigning to a variable, you do not use the $ prefix; e.g. var=1

    • This also applies to assignments in the contexts of variable-declaring builtins declare, local, and export.
  • On referencing a variable (its value) you do use $; e.g., echo "$var"

    • As an exception, there are arithmetic contexts in which you can and generally should reference variables without the $ prefix - see below.

      • Do note that this exception applies only to variables whose values are / can be interpreted as integers (Bash only supports integer arithmetic).
    • As in the example above, you should typically double-quote $-prefixed variable references (expansions) to prevent unwanted modification of the resulting value by the shell by way of its shell expansions, notably by splitting the value into multiple arguments by whitespace (word-splitting) and interpreting the value as a filename pattern (globbing).

    • Using the form ${...} (curly braces around the name / expansion expression) is necessary in the following cases:

      • Disambiguate the variable name in (expandable) strings where characters immediately follow the variable name that Bash would otherwise consider part of the variable name; e.g., echo "${HOME}grown".
      • Parameter expansions that transform the expanded value, such as by prefix and suffix trimming, string replacement, or substring extraction; e.g., echo "${HOME%/*}" yields something like /home, with the shortest suffix (%) matching pattern /* getting trimmed from the value of $HOME; in other words: the last path component is removed.

Arithmetic contexts, in which integer[-interpretable] variables generally need no $ prefix:

  • Explicit arithmetic contexts:

    • $(( ... )) (arithmetic expansion; a POSIX-compliant feature)
      • echo $(( var )) prints 1, the value of $var.
    • (( ... )) (arithmetic expression; a Bash extension)
      • Used as a conditional: (( var )) && echo 'yes' prints yes, because value 1, the value of $var, interpreted (conceptually) as a Boolean, is (conceptually) true.
      • Used to assign the result of a calculation to a variable:
        (( sum = var + var )); echo "$sum" prints 2[1]
  • Implicit arithmetic contexts (all of which are Bash extensions):

    • Inside array indices:
      • arr=( one two ); ndx=0; echo "${arr[ndx+1]}" yields two
    • Inside substring / array-slicing operations (index and offset):
      • str='one'; ndx=0; echo "${str:ndx+1}" yields ne
      • arr=( one two three ); ndx=0; echo "${arr[@]: 0: ndx + 2 }" yields one two
    • Inside [[ ... ]] with arithmetic operators:
      • [[ 1 -eq var ]] && echo 'yes' yields yes.
    • Assignments to variables declared with declare -i or local -i, which marks them as integers:
      • declare -i sum; sum=var; echo "$sum" yields 1
      • declare -i sum=1; sum+=var; echo "$sum" yields 2

Caveat: Typically, it doesn't matter whether you reference variables in these contexts with or without the $ prefix - but there are subtle differences; in short, use the $ prefix in arithmetic contexts only in the following case:

  • You need a nonzero default value that you provide via a parameter expansion; e.g., ${var:-2} defaults to 2 if $var is unset or empty.

[1] (( ... )) has an older equivalent, the obsolescent let.
(( ... )) is preferable, because it doesn't require quoting and is more easily recognized as being related to
$(( ... )) (as well as being visually more distinctive).
Compare (( sum = var + var )) to let 'sum = var + var'

Upvotes: 3

ruakh
ruakh

Reputation: 183564

$var is for a variable expansion: you use it when you want Bash to substitute in the value of the variable. So, for example, this:

var=foo
echo "$var"

sets the variable var to the value foo, and then runs the command echo foo.


Edited to add a few things:

  • $ also has some other related uses; for example, $( ... ) runs the command ..., capturing its output, and expands to that output (minus trailing newlines), and $(( ... )) evaluates the arithmetic expression ... and expands its result:

    cat $(echo foo)      # equivalent to:  cat foo
    cat $((2+3))         # equivalent to:  cat 5
    
  • As codeforester alludes to below, you don't actually need the $ to expand a variable in "arithmetic expressions" (where everything is interpreted as a number), such as are found in (( ... )), $(( ... )), let ..., array indices, and the right-hand-side of variable assignments when the variable has been declared as an integer variable.

  • The Bash Reference Manual, at http://www.gnu.org/software/bash/manual/bashref.html, is detailed and of high quality. It can take a bit of mental adjustment to start thinking the way that Bash does, but it's worth it IMHO.

Upvotes: 5

Related Questions