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

hha*_*fez 241 bash shell ksh sh

要将命令的输出存储为sh/ksh/bash中的变量,您可以执行任一操作

var=$(command)
Run Code Online (Sandbox Code Playgroud)

要么

var=`command`
Run Code Online (Sandbox Code Playgroud)

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

Sie*_*geX 259

反引号/ gravemarks已经被弃用,有利于$()命令替换,因为它$()可以很容易地嵌入自身内部,如同$(echo foo$(echo bar)).还有其他差异,例如如何在反引号/ gravemark版本中解析反斜杠等.

两个原因,请参阅BashFAQ/082,总是更喜欢$(...)语法.

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

  • 良好的链接,但该文本没有_deprecate_反引用支持`$(...)` - 它只是注意到它们作为替代品. (23认同)
  • @NormanGray POSIX可能不会说'弃用*这个词',但它确实说""不建议使用反引号的命令替换"`这只是一个长篇大论的说法,已弃用恕我直言 (23认同)
  • POSIX并没有弃用反引号,而是添加了`$(...)`作为替代方法.反引号没有已知的实现错误,但有许多已知的实现错误与`$(...)`.因此,对于可移植性问题,建议对非嵌套调用使用反引号.`$(...)`需要一个递归解析器,但这并没有与引入该功能的ksh86一起使用.请访问http://www.in-ulm.de/~mascheck/various/cmd-subst/以获取正确实施的列表.符合条件的shell需要支持除案例D.2之外的所有案例. (8认同)
  • 还有在POSIX其他事情需要被看作是'deprecated`,例如使用waitpid函数()`阻止你从'退出看到完整的32位()`参数的`,但除了近期所有炮弹Bourne Shell仍然使用`waitpid()`而不是现在可用26年来的`waitid()`调用. (2认同)

Joh*_*ica 38

他们的行为相同.区别在于语法:它$()``以下更容易嵌套:

listing=$(ls -l $(cat filenames.txt))
Run Code Online (Sandbox Code Playgroud)

listing=`ls -l \`cat filenames.txt\``
Run Code Online (Sandbox Code Playgroud)

  • `echo $(echo\$ abc)`与``echo`echo\$ abc```不同 - "$(echo \`)``和``$(echo \\)也存在差异)`` (10认同)
  • 另一个区别是:`echo foo \`#comment\`` 与 `echo foo $(#comment)`。第二个不行。(用于在多行命令中进行注释。) (2认同)

oco*_*odo 25

当使用较旧的反向标记形式时,反斜杠保留其字面含义,除非后跟$,`或\.第一个反斜杠前面没有反斜杠会终止命令替换.

使用较新的$(command)表单时,括号内的所有字符组成命令; 没有人特别对待.

两种形式都可以嵌套,但后退种类需要以下形式.

`echo \`foo\`` 
Run Code Online (Sandbox Code Playgroud)

相反:

$(echo $(foo))
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 25

2014年7月:在提交f25f5e6(由埃利亚托(devzero2000),2014年4月,Git的2.0)添加到嵌套问题:

反引号形式是命令替换的传统方法,并由POSIX支持.
然而,除了最简单的用途之外,所有这些都很快变得复
特别是,嵌入式命令替换和/或双引号的使用需要小心地使用反斜杠字符进行转义
.

这就是git/Documentation/CodingGuidelines提到的原因:

我们更喜欢$( ... )命令替换; 不像``,它适当地嵌套.
应该是Bourne从第一天开始拼写它的方式,但不幸的是不是.

thiton 评论道:

这就是为什么`echo `foo`` 不能一般地工作,因为固有的模糊性,因为每个``都可以打开或关闭.
由于运气或特殊功能,它可能适用于特殊情况.


2016年1月更新:Git 2.8(2016年3月)完全摆脱了反引号.

请参阅commit ec1b763,commit 9c10377,commit c7b793a,commit 80a6b3f,commit 9375dcf,commit e74ef60,commit 27fe43e,commit 2525c51,commit becd67f,commit a5c98ac,commit 8c311f9,commit 57da049,commit 1d9e86f,commit 78ba28d,commit efa639f,commit 1be2fa0,commit 38e9476,提交8823d2f,提交32858a0,提交cd914d8(2016年1月12日)作者:Elia Pinto(devzero2000).
(由Junio C gitsterHamano合并- -提交e572fef,2016年1月22日)

从Git 2.8开始,它就是全部$(...),不再是`...`.

  • @VonC注意到自己:这是我的第150个死灵法师徽章. (3认同)
  • `$()`也是POSIX指定的 - 引用将反引号描述为"支持POSIX"的方式,暗示这对他们来说是独一无二的,这是误导性的.它只是(20世纪70年代)之前的POSIX Bourne,其中反引号是唯一受支持的语法. (2认同)

Dig*_*oss 5

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

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