我需要引用命令替换吗?

时间:2016-06-20 20:48:16

标签: bash shell quoting

根据Google Shell Style Guide,我应该:

  

除非需要仔细的不加引号扩展,否则始终引用包含变量,命令替换,空格或shell元字符的字符串。

也许我误解了他们的意思"命令替换",但我想知道是否需要在以下示例中使用引号:

VAR="$(echo foo bar)"

3 个答案:

答案 0 :(得分:5)

$(echo foo bar)确实是命令替换。在此特定示例中,您不需要双引号,因为变量赋值会为其右侧创建“双引号上下文”,因此VAR=$(…)等同于VAR="$(…)"

在bash中,您不需要export VAR=$(…)declare VAR=$(…)中的双引号。但是你需要在其他一些sh实现中使用双引号,例如dash。

你需要env VAR=$(…) somecommandmake 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

Source to the command

现在,我们要从文件中提取随机数据包。为此,我们将使用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)