1

In a parameter expansion:

  • Is it always better (or not worse) to double quote a parameter expansion than not? Are there cases where double quoting is not suggested?

  • When is it necessary to add braces around parameter name?

  • when shall we use double quote around parameter expansion instead of braces around parameter name? When the other way around? When does either of the two work?

Thanks.

Tim
  • 101,790

2 Answers2

5

Quote

It is always better to quote parameter expansions when you want to keep the expanded value not split into several words and affected by the value of IFS. For example:

$ IFS=" elr"
$ var="Hello World"
$ printf '<%s> ' $var; echo
<H> <> <> <o> <Wo> <> <d>

$ printf '<%s> ' "$var"; echo <Hello World>

However, there are some very limited instances that require an unquoted expansion to actually get the splitting done:

$ IFS=$' \t\n'
$ var="one two three"
$ array=($var)
$ declare -p array
declare -a array=([0]="one" [1]="two" [2]="three")

Links on the subject:
When is double-quoting necessary?
Gilles
Stéphane Chazelas


Braces

Braces are always required when the characters following the variable name should not be joined with such variable name:

$ var=one
$ echo "The value of var is $varvalue"
The value of var is
$ echo "The value of var is ${var}value"
The value of var is onevalue

From LESS="+/which is not to be interpreted as part" man bash

${parameter}
The braces are required … when parameter is followed by a character which is not to be interpreted as part of its name.

Additionally; braces are required when dealing with any double digit positional parameter.

$ set -- one two t33 f44 f55 s66 s77 e88 n99 t10 e11 t12
$ echo "$11 ${11} $12 ${12}"
one1 e11 one2 t12

Read the manual: LESS="+/enclosed in braces" man bash

When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces

Or LESS="+/with more than one digit" man bash

${parameter}
The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, …

Quotes vs Braces

when shall we use double quote around parameter expansion instead of braces around parameter name? When the other way around? When does either of the two work?

There is no rule for "shall" only the open posibility of using either:

$ var=One
$ echo "ThisIs${var}Var"
ThisIsOneVar

$ echo "ThisIs""$var""Var" ThisIsOneVar

$ echo 'ThisIs'"$var"'Var' ThisIsOneVar

$ echo 'ThisIs'"${var}"'Var' ThisIsOneVar

All the expansions are entirely equivalent, use any one that you like better.

2

One case where braces are necessary is when you are going to use the variable as part of a string:

$ var=test
$ echo "stuff$varmorestuff"
stuff
$ echo "stuff${var}morestuff"
stufftestmorestuff

Without braces the shell thinks I'm trying to expand a variable called varmorestuff which is not set.

From the bash reference manual 3.5.3 Shell Parameter Expansion:

The ‘$’ character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name.

From the shell manual 2.6.2 Parameter Expansion

If the parameter name or symbol is not enclosed in braces, the expansion shall use the longest valid name (see the Base Definitions volume of IEEE Std 1003.1-2001, Section 3.230, Name), whether or not the symbol represented by that name exists.


Additionally braces are required when dealing with any double digit positional parameter.

script.sh

#!/bin/sh
if [ "$1" = 'correct' ]; then
        echo "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}"
else
        echo "$2" "$3" "$4" "$5" "$6" "$7" "$9" "$9" "$10"
fi

In action:

$ ./script.sh one two three four five six seven eight nine ten
two three four five six seven nine nine one0
$ ./script.sh correct two three four five six seven eight nine ten
two three four five six seven eight nine ten

From the bash manual 3.4.1 Positional Parameters

Positional parameter N may be referenced as ${N}, or as $N when N consists of a single digit.

From the shell manual 2.6.2 Parameter Expansion

The parameter name or symbol can be enclosed in braces, which are optional except for positional parameters with more than one digit or when parameter is followed by a character that could be interpreted as part of the name. The matching closing brace shall be determined by counting brace levels, skipping over enclosed quoted strings, and command substitutions.

jesse_b
  • 37,005
  • In the cases that you suggest to use braces around parameter names, can we double quote the parameter expansion instead? – Tim Feb 04 '18 at 02:51
  • technically it would work if you did echo stuff"$var"morestuff but that is assuming you have no white space. You could also do echo 'stuff'"$var"'morestuff' but that is what the braces are for. – jesse_b Feb 04 '18 at 02:54