问题
According to the Google Shell Style Guide, I should:
Always quote strings containing variables, command substitutions, spaces or shell meta characters, unless careful unquoted expansion is required.
Maybe I am misinterpreting what they mean by "command substitutions", but I am wondering if there is any need to use quotes in the following example:
VAR="$(echo foo bar)"
回答1:
$(echo foo bar)
is indeed a command substitution. In this specific example, you don't need double quotes because a variable assignment creates a “double quote context” for its right-hand side, so VAR=$(…)
is equivalent to VAR="$(…)"
.
In bash, you don't need double quotes in export VAR=$(…)
or declare VAR=$(…)
. But you do need the double quotes in some other sh implementations such as dash.
You do need double quotes in env VAR=$(…) somecommand
, in make VAR=$(…)
, etc. It isn't the equal sign that makes the double quotes optional, it's the fact that the equal sign is parsed by the shell as an assignment.
There are a few other contexts where the double quotes are optional, but you can't go wrong with the simple rule: always use double quotes around variable and command substitutions unless you want the split+glob operator.
回答2:
EDIT: (A command substitution is $( )
and the back-tick almost-equivalent, so you're likely interpreting it correctly)
It will certainly not hurt to quote strings in general in shell scripts, unless you're actually relying on globbing etc. to take effect.
In this simple example, the double-quotes are certainly not needed, but for consistency I would probably add them.
If you instead have
VAR=$( echo $foo $bar )
... then I would certainly quote both variables and expression:
VAR="$( echo "$foo" "$bar" )"
especially if any of those variable contained external input or if you knew they had globbing-characters in them.
EDIT: As user @CharlesDuffy points out, the outer double-quotes here are still not needed. I would still add them to be consistent with other variable assignments that do need quoting.
回答3:
When not to quote a command substitution?
Answer: When you want the output of the command substitution to be treated as separate arguments.
Example:
We want to extract specific packets (packet numbers 1, 5, 10 and 20) from a .pcap
file. The relevant command is the following:
editcap -r capture.pcap select.pcap 1 5 10 20
(Source to the command)
Now, we want to extract random packets from the file. To do that, we will use shuf
from GNU Coreutils.
shuf -i 0-50 -n 4
8
24
20
31
The command above has generated 4 random numbers between 0 and 50.
Using it with editcap
:
editcap -r source.pcap select.pcap "$(shuf -i 0-50 -n 4)"
editcap: The specified packet number "1
34
4
38" isn't a decimal number
As you can see, quoting the command substitution has resulted in the output string of the shuf
to be treated as a single big string, including the newlines and whatnot as well. That is, putting quotes has resulted in the equivalent of the following command:
editcap -r source.pcap select.pcap "1
34
4
38"
Instead, we want Bash the chop the output of shuf
and insert this chopped output as separate arguments to editcap
. Omitting the quotes accomplishes that:
editcap -r source.pcap select.pcap $(shuf -i 0-50 -n 4)
来源:https://stackoverflow.com/questions/37931555/do-i-need-to-quote-command-substitutions