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


Answers:


274

不推荐使用反引号/标记,$()因为它$()可以像在中一样轻易地嵌套在命令中,以代替命令$(echo foo$(echo bar))。还有其他区别,例如反引号/标记版本中反斜杠的解析方式等。

出于多种原因,请参阅BashFAQ / 082,以始终首选使用$(...)语法。

另请参阅POSIX规范以获取有关各种差异的详细信息。


25
链接很好,但是该文本并不赞成使用反引号$(...)-只是将它们引为备选。
Norman Gray

24
@NormanGray POSIX可能不会说不赞成的单词,但它确实说了"the backquoted variety of command substitution is not recommended"这只是说不赞成IMHO的长篇大论
SiegeX 2015年

11
POSIX并不反对使用反引号,而是将其添加$(...)为替代方法。反引号没有已知的实现错误,但是有许多已知的实现错误$(...) 。因此,对于可移植性问题,建议对非嵌套呼叫使用反引号。$(...)需要一个递归解析器,但是未与引入该功能的ksh86一起使用。在in-ulm.de/~mascheck/various/cmd-subst中 查看正确的实现列表。合格的外壳需要支持除情况D.2之外的所有情况。
2016年

2
POSIX中还有其他需要注意的事情deprecated,例如,使用waitpid()that会阻止您从exit()参数中看到完整的32位,但是除最近的Bourne Shell之外的所有Shell仍使用waitpid()而不是waitid()现在可用的调用,因为26年
2016年

答案中的链接暗示反引号和之间有一些区别$(),这在文档的此部分中有更多说明。不同之处不仅在于嵌套。
某位程序员花了

39

它们的行为相同。区别是语法上的:嵌套$()``

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

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

10
echo $(echo \$abc)是不一样的echo `echo \$abc`‍- $(echo \`)$(echo \\)
Peter.O 2015年

另一个区别是:echo foo `#comment`vs echo foo $(#comment)。第二个不起作用。(用于在多行命令中进行注释。)
wisbucky

27

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

反引号形式是命令替换的传统方法,并且受POSIX支持。
但是,除最简单的用途外,所有其他用途都会迅速变得复杂。
特别地,嵌入式命令替换和/或双引号的使用要求使用反斜杠字符进行仔细的转义

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

我们更喜欢$( ... )命令替换;与``不同,它正确嵌套
从第一天开始,它就应该是伯恩(Bourne)拼写的方式,但不幸的是事实并非如此。

蒂顿 评论

这就是为什么`echo `foo`` 由于固有的含糊性而通常无法正常工作的原因,因为每个模糊性都``可以打开或关闭。
由于运气或特殊功能,在某些特殊情况下可能会起作用。


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 gitsterHamano合并--commit e572fef中,2016年1月22日)

从Git的2.8起,它是所有$(...),没有更多的`...`


2
$()也是POSIX指定的-用引号将反引号描述为“受POSIX支持”,以暗示这对他们来说是独一无二的。它是POSIX Bourne之前(1970年代)唯一支持的反引号语法。
Charles Duffy

25

当使用较旧的反引号形式时,反斜杠保留其字面意思,除非后面加$,`或\。没有反斜杠的第一个反引号会终止命令替换。

当使用较新的$(command)形式时,括号之间的所有字符组成命令;没有一个被特别对待。

两种形式都可以嵌套,但是反勾号需要以下形式。

`echo \`foo\`` 

相对于:

$(echo $(foo))

1
较小的更正,反引号版本和$()POSIX兼容。
SiegeX'1

5

除了可以在命令内部使用哪些未转义的字符外,几乎没有什么区别。您甚至可以在$(...)命令中放入`...`命令反之亦然),以进行更复杂的两级深度命令替换。

反斜杠字符/运算符的解释略有不同。除其他事项外,当嵌套`...`替换命令时,您必须使用\转义内部的`字符而使用$()替换,它将自动理解嵌套。


0

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

请注意以下行为:

A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"

您将得到以下结果:

$A
A_VARIABLE

 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.