Quoting and not quoting command substitution in the Bourne shell
Over on the Fediverse, I said something:
Bourne shell trivia of the day:
var=$(program ...)
is the same as
var="$(program ...)"
so the quotes are unnecessary.But:
program2 $(program ...)
is not the same as:
program2 "$(program ..)"
and often the quotes are vital.(I have been writing the variable assignment as var="$(...)" for ages without realizing that the quotes were unnecessary.)
This came about because I ran an old shell script through shellcheck, which recommended replacing its use
of var=`...`
with var=$(...)
, and then I got to wondering why
shellcheck wasn't telling me to write the second as var="$(...)"
for safety against multi-word expansions. The answer is of course
that multi-word expansion doesn't happen in this context; even if
the $(...) produces what would normally be multiple words of output,
they're all assigned to 'var
' as a single word.
On the one hand, this is what you want; there's almost no circumstance
where you want a command that produces multiple words of output to
have the first word assigned to 'var
' and then the rest interpreted
as a command and its arguments.
On the other hand, the Bourne shell is generally not known for being
friendly about its quoting. It would be perfectly in character for
the Bourne shell to require you to quote the '$(...)
' even in
variable assignment.
On the one hand, shellcheck doesn't complain about the quoted version
and it's consistent with quoting $(...)
in other circumstances
(when it really does matter). On the other hand, you can easily
forget or not know (as I did) that the quoting is unnecessary here,
and then you can be alarmed when you see an unquoted 'var=$(...)
'
in the wild or have it suggested. Since I've mostly written the
quoted version, I'll probably continue doing so in my scripts unless
I'm dealing with a script that already has some unquoted examples,
where I should probably make everything unquoted so that no one
reading the script in the future ever thinks there's a difference
between the two.
|
|