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

问题描述 投票:0回答:7

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

var=$(command)

var=`command`

这两种方法有什么区别?

bash shell ksh sh
7个回答
329
投票

反引号/墓记已被弃用,转而使用

$()
进行命令替换,因为
$()
可以轻松地嵌套在自身内部,如
$(echo foo$(echo bar))
中所示。还有其他差异,例如反斜杠在反引号/墓标版本中如何解析等。

请参阅 BashFAQ/082,出于多种原因,始终更喜欢 $(...) 语法。

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


43
投票

他们的行为是一样的。区别在于语法:嵌套

$()
``
更容易:

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

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

31
投票

2014 年 7 月:commit f25f5e6(由 Elia Pinto (

devzero2000
),2014 年 4 月,Git 2.0)增加了嵌套问题:

反引号形式是命令替换的传统方法,并且受 POSIX 支持。
但是,除了最简单的用途之外,所有用途很快就会变得复杂。
特别是,嵌入式命令替换和/或双引号的使用需要 小心使用反斜杠字符转义

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

我们更喜欢使用

$( ... )
进行命令替换; 与``不同,它正确嵌套
Bourne 从第一天起就应该这么拼写,但不幸的是不是。

thiton评论

这就是为什么

`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 Hamano --
gitster
--
合并于 commit e572fef,2016 年 1 月 22 日)

从 Git 2.8 开始,都是

$(...)
,不再是
`...`


29
投票

当使用旧的反斜杠形式时,反斜杠保留其字面含义,除非后面跟着 $、` 或 \。前面没有反斜杠的第一个反引号终止命令替换。

当使用较新的

$(command)
形式时,括号之间的所有字符组成命令;没有一个受到特殊对待。

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

`echo \`foo\`` 

相对于:

$(echo $(foo))

6
投票

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

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


1
投票

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

注意这种行为:

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

您将得到以下结果:

$A
A_VARIABLE

 


0
投票

一个新颖的案例是如何处理评论。反引号内的散列字符创建以第二个反引号字符结束的注释,从而有效地创建了一种具有中行注释的方法。使用较新的首选语法,注释会继续到行尾。

使用反引号:

$ echo "Goodbye` # Cruel` World"

打印:

Goodbye World

使用首选语法:

$ echo "Goodbye$( # Cruel) World"

导致错误:

sh: 1: Syntax error: end of file unexpected (expecting ")")

使用首选语法获得相同的结果需要将命令分成两行:

$ echo "Goodbye$( # Cruel
> ) World"

然后它会打印与单行反引号版本相同的值。

要从 repl 中亲自测试这一点,您可能必须这样称呼它:

$ sh -c 'echo "Goodbye$( # Cruel) World"'
© www.soinside.com 2019 - 2024. All rights reserved.