要将命令的输出存储为 sh/ksh/bash 中的变量,您可以执行以下任一操作
var=$(command)
或
var=`command`
这两种方法有什么区别?
反引号/墓记已被弃用,转而使用
$()
进行命令替换,因为 $()
可以轻松地嵌套在自身内部,如 $(echo foo$(echo bar))
中所示。还有其他差异,例如反斜杠在反引号/墓标版本中如何解析等。
请参阅 BashFAQ/082,出于多种原因,始终更喜欢 $(...) 语法。
另请参阅 POSIX 规范,了解有关各种差异的详细信息。
他们的行为是一样的。区别在于语法:嵌套
$()
比 ``
更容易:
listing=$(ls -l $(cat filenames.txt))
与
listing=`ls -l \`cat filenames.txt\``
2014 年 7 月:commit 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
)。gitster
-- 合并于 commit e572fef,2016 年 1 月 22 日)
从 Git 2.8 开始,都是
$(...)
,不再是 `...`
。
当使用旧的反斜杠形式时,反斜杠保留其字面含义,除非后面跟着 $、` 或 \。前面没有反斜杠的第一个反引号终止命令替换。
当使用较新的
$(command)
形式时,括号之间的所有字符组成命令;没有一个受到特殊对待。
两种形式都可以嵌套,但反勾号类型需要以下形式。
`echo \`foo\``
相对于:
$(echo $(foo))
除了可以在命令内部使用的未转义字符之外,几乎没有什么区别。您甚至可以将 `...` 命令放入 $(...) 命令中(反之亦然),以实现更复杂的两级深度命令替换。
反斜杠字符/运算符的解释略有不同。除此之外,当嵌套 `...` 替换命令时,您必须使用 \, 转义内部 ` 字符,而使用 $() 替换它会自动理解嵌套。
“这两种方法有什么区别?”
注意这种行为:
A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"
您将得到以下结果:
$A
A_VARIABLE
一个新颖的案例是如何处理评论。反引号内的散列字符创建以第二个反引号字符结束的注释,从而有效地创建了一种具有中行注释的方法。使用较新的首选语法,注释会继续到行尾。
使用反引号:
$ 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"'