$VAR vs ${VAR} and to quote or not to quote

I can write


the end result to me all seems about the same. Why should I write one or the other? are any of these not portable/POSIX?

Asked By: xenoterracide


VAR=$VAR1 is a simplified version of VAR=${VAR1}. There are things the second can do that the first can’t, for instance reference an array index (not portable) or remove a substring (POSIX-portable). See the More on variables section of the Bash Guide for Beginners and Parameter Expansion in the POSIX spec.

Using quotes around a variable as in rm -- "$VAR1" or rm -- "${VAR}" is a good idea. This makes the contents of the variable an atomic unit. If the variable value contains blanks (well, characters in the $IFS special variable, blanks by default) or globbing characters and you don’t quote it, then each word is considered for filename generation (globbing) whose expansion makes as many arguments to whatever you’re doing.

$ find .
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'

$ find .
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
./spaced filename

On portability:
According to POSIX.1-2008 section 2.6.2, the curly braces are optional.

Answered By: Shawn J. Goff

${VAR} and $VAR are exactly equivalent. For a plain variable expansion, the only reason to use ${VAR} is when parsing would otherwise grab too many characters into the variable name, as in ${VAR1}_$VAR2 (which without braces would be equivalent to ${VAR1_}$VAR2). Most adorned expansions (${VAR:=default}, ${VAR#prefix}, …) require braces.

In csh, tcsh or zsh (when the ksharrays option is not enabled), $var[1] is the same as ${var[1]} and $var:modifier the same as ${var:modifier}, so you also want the braces there if you want the $var expansion followed by a literal [1] or :modifier: ${var}[1] ${var}:modifier.

In a scalar (as opposed to array or associative array) variable assignment, field splitting (i.e. splitting at whitespace in the value) and pathname expansion (i.e. globbing) are turned off, so VAR=$VAR1 is exactly equivalent to VAR="$VAR1", in all POSIX shells and in all pre-POSIX sh that I’ve heard of. (POSIX ref: simple commands). For the same reason, VAR=* reliably sets VAR to the literal string *; of course VAR=a b sets VAR to a since the b is a separate word in the first place. Generally speaking, double quotes are unnecessary where the shell syntax expects a single word, for example in case … in (but not in the pattern), but even there you need to be careful: for example POSIX specifies that redirection targets (>$filename) don’t require quoting in scripts, but a few shells including bash do require the double quotes even in scripts. See When is double-quoting necessary? for a more thorough analysis.

You do need the double quotes in other cases, in particular in export VAR="${VAR1}" (which can equivalently be written export "VAR=${VAR1}") in many shells (POSIX leaves this case open). The similarity of this case with simple assignments, and the scattered nature of the list of cases where you don’t need double quotes, are why I recommend just using double quotes unless you do want to split and glob.

ls -la

lrwxrwxrwx.  1 root root      31 Nov 17 13:13 prodhostname
lrwxrwxrwx.  1 root root      33 Nov 17 13:13 testhostname
lrwxrwxrwx.  1 root root      32 Nov 17 13:13 justname

end then:

    if [ ! -f /dirname/${env}hostname ]

worth mentioning as a clearer example of using curlies

Answered By: ninjabber


Consider that double-quote is used for variable expansion, and single-quote is used for strong-quoting, i.e., sans expansion.




for item in "$this" "$that" "$these" "$those"; do echo "$item"; done

It might be worthwhile to mention that you should use quotation wherever possible for several reasons, among the best of which are that it’s considered best practice, and for readability. Also because Bash is quirky at times and often for seemingly illogical or unreasonable/unexpected ways, and quotation changes implicit expectations to explicit, which reduces that error surface (or potential-for therein).

And while it’s completely legal to not quote, and will work in most cases, that functionality is provided for convenience and is probably less portable. the fully-formal practice guaranteed to reflect intent and expectation is to quote.


Now consider also that the construct "${somevar}" is used for substitution operations. Several use cases, such as replacement, and arrays.

Replacement (stripping):

foo="${thisfile%.*}"   # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}"  # removes longest matching

for item in "$foo" "$bar"; do echo "$item"; done

Replacement (replacement):

foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}"   #single occurrence
bar="${foobar//least/most}"  #global occurrence (all)

for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful


mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls  
alpha=($(ls temp/*))

echo "$alpha"         #  temp/foo.txt
echo "${alpha}"       #  temp/foo.txt
echo "${alpha[@]}"    #  temp/bar.txt  temp/foobar.txt  temp/foo.txt
echo "${#alpha}"      #  12 # length of first element (implicit index [0])
echo "${#alpha[@]}"   #  3  # number of elements
echo "${alpha[1]}"    #  temp/foobar.txt # second element
echo "${#alpha[1])"   #  15 # length of second element

for item in "${alpha[@]}"; do echo "$item"; done

All of this is barely scratching the surface of the "${var}" substitution construct. The definitive reference for Bash shell scripting is the libre online reference, TLDP The Linux Documentation Project https://www.tldp.org/LDP/abs/html/parameter-substitution.html

Answered By: SYANiDE

Some times you have to use ${var} instead of $var when you parse data from user input say in website to server to be executed $var won’t work
for example


the posted data will work if it ${var} not $var

Answered By: Abdelrahman Saleh