根据Google Shell Style Guide,我应该:
除非需要仔细的不加引号扩展,否则始终引用包含变量,命令替换,空格或shell元字符的字符串。
也许我误解了他们的意思"命令替换",但我想知道是否需要在以下示例中使用引号:
VAR="$(echo foo bar)"
答案 0 :(得分:5)
$(echo foo bar)
确实是命令替换。在此特定示例中,您不需要双引号,因为变量赋值会为其右侧创建“双引号上下文”,因此VAR=$(…)
等同于VAR="$(…)"
。
在bash中,您不需要export VAR=$(…)
或declare VAR=$(…)
中的双引号。但是你需要在其他一些sh实现中使用双引号,例如dash。
你需要env VAR=$(…) somecommand
,make VAR=$(…)
中的双引号,等等。这不是使双引号可选的等号,它是等于同等的事实标志由shell解析为一个赋值。
有a few other contexts where the double quotes are optional,但您可以通过简单规则出错:always use double quotes around variable and command substitutions除非you want the split+glob operator。
答案 1 :(得分:2)
编辑:(命令替换为$( )
,后退符号几乎等同,因此您可能正确地解释它)
在shell脚本中引用字符串一定不会有什么坏处,除非你真的依赖于globbing等来生效。
在这个简单的例子中,当然不需要双引号,但为了保持一致性,我可能会添加它们。
如果您改为
VAR=$( echo $foo $bar )
...然后我肯定会引用变量和表达式:
VAR="$( echo "$foo" "$bar" )"
尤其是如果这些变量中的任何一个包含外部输入,或者如果您知道它们中包含全局字符。
编辑:正如用户@CharlesDuffy指出的那样,这里的外部双引号仍然不需要。我仍然会将它们添加到与需要引用的其他变量赋值一致。
答案 2 :(得分:1)
答案:当您希望将命令替换的输出视为单独的参数时。
我们希望从.pcap
文件中提取特定数据包(数据包编号1,5,10和20)。相关命令如下:
editcap -r capture.pcap select.pcap 1 5 10 20
现在,我们要从文件中提取随机数据包。为此,我们将使用GNU Coreutils中的shuf
。
shuf -i 0-50 -n 4
8
24
20
31
上面的命令生成了0到50之间的4个随机数。
将其与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
正如您所看到的,引用命令替换导致shuf
的输出字符串被视为单个大字符串,包括换行符和诸如此类的东西。也就是说,输入引号会导致相当于以下命令:
editcap -r source.pcap select.pcap "1
34
4
38"
相反,我们希望Bash切断shuf
的输出并将此切断的输出作为单独的参数插入editcap
。省略引号可以实现:
editcap -r source.pcap select.pcap $(shuf -i 0-50 -n 4)