Is there any valid reason not to put all variables in a shell script in quotes? ("Not knowing any better" is not a valid reason in my opinion.)
Generally speaking, quoting variables makes sure that they are seen as one variable, should they contain spaces or other special characters. So why would anyone ever go for an "unsafe" way and not quote variables?
So why would anyone ever go for an "unsafe" way and not quote variables?
That is almost never the right thing to do. Newcomers to shell are almost always better served by placing variables in double-quotes. For advanced users, I can think of three possible exceptions:
An example could be:
glob=*.xml
# Do something, possibly creating xml files
rm $glob
Here, pathname expansion is performed on glob
not when it is defined but when rm
is executed. There might be times when such late evaluation is beneficial.
For bash, one can can create an array with glob=(*.xml)
. This is likely superior for every case except when late evaluation is important.
An example is handling simple command options when you want compatibility with POSIX shells that that don't support arrays:
opts=
[ -f "$onething" ] && opts="-a"
[ -f "$another" ] && opts="$opts -b"
cmd $opts
Here, word splitting allows the command cmd
to see multiple options. If $opts
were in quotes, it would see only one string.
This approach for multiple options is limited to simple options. For bash, one would replace the variable opts
with an array which works much better when options are more complex. POSIX shells, however, do not support named arrays so using a variable like this is viable as a second-best work-around.
Inside [[...]]
, you may sometimes want the operator =
to test for a glob match. If so the right-hand side must be unquoted:
$ glob=*.xml
$ [[ file.xml = "$glob" ]] && echo yes || echo no
no
$ [[ file.xml = $glob ]] && echo yes || echo no
yes
Glob matches are handy when you want them. If you weren't expecting them, they can be a disaster. Thus, unless you explicitly want a glob match, the right-hand side must be quoted.
Likewise if you want the =~
operation to test for a regex match:
$ regex=fi.*ml
$ [[ file.xml =~ "$regex" ]] && echo yes || echo no
no
$ [[ file.xml =~ $regex ]] && echo yes || echo no
yes
(Hat tip: Gordon Davisson)
Well, to me "reducing unnecessary syntactic noise to make the script more readable" >>could be<< a valid reason, at least in some peoples' minds.
I'm assuming that there are situations where the variable CANNOT have spaces in them; e.g.
COUNT=1
FILENAME=file$COUNT.txt
and that are other cases where it really doesn't matter how the embedded spaces are treated; e.g.
echo the filename is $NAME
But if you don't accept that as "valid" (and I think you won't from the tone of your question), then I guess the answer is No.
And obviously, there are situations where quoting would suppress behavior that you actually require; e.g. tokenization or globbing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With