2014-11-24 40 views
6

我读过的几乎所有地方,包括谷歌的bash脚本风格指南提及引用命令替换的必要性(当然除非特别需要)。是否有必要在bash中的变量赋值时引用命令替换?

我了解在一般使用期间引用命令替换的时间/地点/原因。例如:echo "$(cat <<< "* useless string *")"而非echo $(...)

然而,对于变量赋值具体而言,我看到这样的例子很多这样: variable="$(command)"

然而,我已经发现没有实例,其中variable=$(command)是不等价的。

variable="$(echo "*")"variable=$(echo "*")都将值设置为'*'。

任何人都可以给出任何情况下,在变量分配期间不加引用会导致一个问题吗?

+0

好问题!我做了很多测试,看起来他们完全一样,没有区别。 – fedorqui 2014-11-24 09:26:47

+0

我想他问的问题可能会发生在$ cmd,$ {cmd}。在替代和If子句中,我们需要“”在那里。请纠正,如果我错了 – 2014-11-24 09:29:10

回答

6

shell不执行字分割用于变量赋值(它由POSIX标准化,您可以依赖它)。因此,你不需要双引号(但你可以使用,而不必使不同的结果)在

variable=$(command) # same as variable="$(command)" 

然而,字拆分执行命令之前进行,所以在

echo $(command) 
echo "$(command)" 

结果可能不一样。后者保留所有多空间序列,而前者使每个单词成为不同的回声。由您来决定哪个是理想的行为。

有趣的壳怪癖:还有一个地方引用一个替代或没有差别,即在case expr in构造中的表达。

case $FOO in 
    (frob) ...;; 
esac 

无法区分

case "$FOO" in 
    (frob) ...;; 
esac 
+2

这就是这个答案所说的。 – 2014-11-24 09:34:36

+0

如果需要,你能给出一个链接到POSIX标准的确切部分吗?我很难找到它。 – Lucas 2016-05-17 12:09:41

+2

@Lucas我会翻译2.9.1简单命令,http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01中的#4:*“每个变量赋值都应扩展为波形扩展,参数扩展,命令替换,算术扩展和赋值之前的引用移除“。*这里没有说明分词。 – Jens 2016-05-17 15:20:33

-2

测试有这么多不同的命令,这是一样的。无法找到差异。

+1

这不是问题的答案。看看有什么不同,试着'echo $(echo -e“hello \ nworld”)''echo'echo(echo -e“hello \ nworld”)“' – jeb 2017-01-04 14:32:25

4

当使用bash,这两条线是100%当量:

variable="$(command)" 
variable=$(command) 

而这两个都没有:

echo $(command) 
echo "$(command)" 

唉,人脑是不是一个计算机。重复工作尤其不够可靠。

因此,如果您混合使用样式(即,当您使用命令参数时引用,但在分配变量时不引用),那么偶尔会发生错误。

更糟糕的是,偶尔你会希望将命令结果扩展为单个单词。读下你的代码的下一个人会怀疑他是否在看bug。

结束语:由于前两行是相同的,所以在平均大脑上总是容易引用$()(即使没有必要),以确保您始终在必要时引用它。

+2

好吧,那有道理,如此频繁......当我第一次开始编写shell脚本时,我把它作为一般规则引用。现在我对它更加熟悉了,我只是试图消除任何多余或不必要的东西。 – Six 2014-11-24 10:26:58