shell编程中的$(command)和`command`有什么区别?

在sh / ksh / bash中将一个命令的输出作为一个variables来存储,你也可以这样做

MY_VAR=$(command) #or you can do MY_VAR=`command` 

两种方法之间有什么区别?

由于$()可以很容易地在$(echo foo$(echo bar))嵌套,所以反引号/ gravemarks已经被弃用,用于replace命令$() $(echo foo$(echo bar)) 。 还有一些细微的差别,例如反斜杠/ gravemark版本中反斜杠的parsing方式。

有关各种差异的详细信息,请参阅POSIX规范。

他们performance一样。 不同之处在于语法上:嵌套$()比嵌套更容易:

 listing=$(ls -l $(cat filenames.txt)) 

 listing=`ls -l \`cat filenames.txt\`` 

当使用较旧的back-tickforms时,反斜杠将保留其字面含义,除非后跟$,`或\。 第一个反斜杠前面没有反斜杠终止命令replace。

当使用较新的$(command)forms时,括号之间的所有字符构成命令; 没有一个是专门处理的

这两种forms都可以嵌套,但是反转forms需要以下forms。

 `echo \`foo\`` 

而不是:

 $(echo $(foo)) 

2014年7月: 提交f25f5e6 (由Elia Pinto( devzero2000 ) ,2014年4月,Git 2.0)增加了嵌套问题:

反引用表单是传统的命令replace方法,由POSIX支持。
但是,除了最简单的用途之外,所有这些都很快就变得复杂了
特别是,embedded的命令replace和/或使用双引号需要仔细转义反斜杠字符

这就是为什么git / Documentation / CodingGuidelines提到:

我们更喜欢$( ... )来replace命令; 不像“,它正确地嵌套
本应该是Bourne从第一天开始拼写的方式,但不幸的是没有。

thiton 评论道 :

这就是为什么`echo `foo``通常不起作用,因为每个``可以打开或closures,因为它固有的不明确性。
由于运气或特殊function,它可能适用于特殊情况。


2016年1月更新:Git 2.8(2016年3月)彻底清除反引号。

参见提交ec1b763 提交9c10377 提交c7b793a 提交80a6b3f 提交9375dcf 提交e74ef60 提交27fe43e 提交2525c51 提交becd67f 提交a5c98ac 提交8c311f9 提交57da049 提交1d9e86f 提交78ba28d 提交efa639f 提交1be2fa0 提交38e9476 , 提交8823d2f , 提交32858a0 , 提交cd914d8 (2016年1月12日)通过Elia Pinto( devzero2000 ) 。
(由Junio C gitster合并- gitster – in e572fef ,2016年1月22日)

从Git2.8开始,全是$(...) ,不再有`...`

除了在命令中可以使用的非转义字符之外,几乎没有什么区别。 你甚至可以在$(…)之内放置`…`命令反之亦然),以进行更复杂的两级深层命令replace。

对反斜杠字符/运算符的解释略有不同。 除此之外,嵌套`…`replace命令时,必须使用\转义内部字符而使用$()replace则会自动理解嵌套。