You can always show the effects of variable quoting with printf
.
Word splitting done on var1
:
$ var1="hello world"
$ printf '[%s]\n' $var1
[hello]
[world]
var1
quoted, so no word splitting:
$ printf '[%s]\n' "$var1"
[hello world]
Word splitting on var1
inside $()
, equivalent to echo "hello" "world"
:
$ var2=$(echo $var1)
$ printf '[%s]\n' "$var2"
[hello world]
No word splitting on var1
, no problem with not quoting the $()
:
$ var2=$(echo "$var1")
$ printf '[%s]\n' "$var2"
[hello world]
Word splitting on var1
again:
$ var2="$(echo $var1)"
$ printf '[%s]\n' "$var2"
[hello world]
Quoting both, easiest way to be sure.
$ var2="$(echo "$var1")"
$ printf '[%s]\n' "$var2"
[hello world]
Globbing problem
Not quoting a variable can also lead to glob expansion of its contents:
$ mkdir test; cd test; touch file1 file2
$ var="*"
$ printf '[%s]\n' $var
[file1]
[file2]
$ printf '[%s]\n' "$var"
[*]
Note this happens after the variable is expanded only. It is not necessary to quote a glob during assignment:
$ var=*
$ printf '[%s]\n' $var
[file1]
[file2]
$ printf '[%s]\n' "$var"
[*]
Use set -f
to disable this behaviour:
$ set -f
$ var=*
$ printf '[%s]\n' $var
[*]
And set +f
to re-enable it:
$ set +f
$ printf '[%s]\n' $var
[file1]
[file2]