要将命令的输出作为变量存储在sh/ksh/bash中,可以执行以下操作之一
var=$(command)
或
var=`command`
如果这两种方法有什么区别的话,那有什么区别呢?
j0pj023g1#
反引号/gravemark已经被弃用,而支持$()作为命令替换,因为$()可以像$(echo foo$(echo bar))一样轻松地嵌套在自己内部。还有其他的区别,比如反斜线在反勾号/gravemark版本中是如何解析的,等等。请参阅BashFAQ/082,了解始终首选$(...)语法的几个原因。有关各种差异的详细信息,请参阅POSIX规范。
$()
$(echo foo$(echo bar))
5sxhfpxr2#
他们的行为是一样的。区别在于语法:嵌套$()比嵌套````更容易:
listing=$(ls -l $(cat filenames.txt))
vs.
listing=`ls -l \`cat filenames.txt\``
6qftjkof3#
2014年7月:commit f25f5e6(by Elia Pinto ( devzero2000 ),April 2014,Git 2.0)增加了嵌套问题:反引号形式是命令替换的传统方法,并且由POSIX支持。
devzero2000
**然而,除了最简单的用法外,所有的用法都很快变得复杂。
特别是,嵌入式命令替换和/或双引号的使用需要小心地使用反斜杠字符**进行转义。这就是为什么git/Documentation/CodingGuidelines提到:我们更喜欢$( ... )作为命令替换;**不像,它正确地嵌套**。 伯恩从第一天起就应该这样拼写,但不幸的是不是。 [thiton](https://stackoverflow.com/users/847601/thiton)评论: 这就是为什么echo foo```一般不工作的原因,因为每个````都可以打开或关闭,因此存在固有的模糊性。 它可能会因运气或特殊功能而适用于特殊情况。 2016年1月更新:Git 2.8(2016年3月)完全去除了反引号。 参见[commit ec1b763](https://github.com/git/git/commit/ec1b763d05bb03d8741c1363d7acf4ccb7153f6d)、[commit 9c10377](https://github.com/git/git/commit/9c1037751c0204c494b1ed49e8c1d94429ea78b1)、[commit c7b793a](https://github.com/git/git/commit/c7b793a17d92350632c51a24e06b6a3dc4a93c2b)、[commit 80a6b3f](https://github.com/git/git/commit/80a6b3f0d54d0df6c6994df5486433bf0b9a54c0)、[commit 9375dcf](https://github.com/git/git/commit/9375dcf3b9bb1e462e28d5017165e1c7fa741c77)、[commit e74ef60](https://github.com/git/git/commit/e74ef604974192712c38f77cd751b00ad36e1378)、[commit 27fe43e](https://github.com/git/git/commit/27fe43e869f4ee8865beeedf6f2bbbab07cf0c7c)、[commit 2525c51](https://github.com/git/git/commit/2525c5170f1088dac0aeb18444041f9fff04761a)、[commit becd67f](https://github.com/git/git/commit/becd67fd281fa0efdf8f6346f311954a237dc991)、[commit a5c98ac](https://github.com/git/git/commit/a5c98acec6ad8e8c397b1001621a4edfacc98516)、[commit 8c311f9](https://github.com/git/git/commit/8c311f96a5a089d2f35654e9af7c44377a27839b)、[commit 57da049](https://github.com/git/git/commit/57da04965d56c7d7da6a00c3fb6fc3981cf0ba9a)、[commit 1d9e86f](https://github.com/git/git/commit/1d9e86f80d2ede6829c57ef4b22e4dd8b162cc7e)、[commit 78ba28d](https://github.com/git/git/commit/78ba28d84b5be8cbb1d5d5e7d65b5522739ad5ce)、[commit efa639f](https://github.com/git/git/commit/efa639fe6b850de699b675bf3e9c4b35f54f54bc)、[commit 1be2fa0](https://github.com/git/git/commit/1be2fa02b5ac97346e6745c767c559ee363ff378)、[commit 38e9476](https://github.com/git/git/commit/38e947660b2bb09e035f91b682b7011c2808052e),[commit 8823d2f](https://github.com/git/git/commit/8823d2fa792efbc89d3ab1392a4b064e8fbd6705),[commit 32858a0](https://github.com/git/git/commit/32858a01506b22963cfd5f8c8db95486f26133af),[commit cd914d8](https://github.com/git/git/commit/cd914d8090d64c8df1b0c45327de7dacdf370a09)(12 Jan 2016)by [Elia Pinto (devzero2000)](https://github.com/devzero2000) . (由[Junio C Hamano --gitster--](https://github.com/gitster)合并至[commit e572fef](https://github.com/git/git/commit/e572fef9d459497de2bd719747d5625a27c9b41d),2016年1月22日) 从Git 2.8开始,它都是$(...)`,不再是...。
$( ... )
,它正确地嵌套**。 伯恩从第一天起就应该这样拼写,但不幸的是不是。 [thiton](https://stackoverflow.com/users/847601/thiton)评论: 这就是为什么
foo```一般不工作的原因,因为每个````都可以打开或关闭,因此存在固有的模糊性。 它可能会因运气或特殊功能而适用于特殊情况。 2016年1月更新:Git 2.8(2016年3月)完全去除了反引号。 参见[commit ec1b763](https://github.com/git/git/commit/ec1b763d05bb03d8741c1363d7acf4ccb7153f6d)、[commit 9c10377](https://github.com/git/git/commit/9c1037751c0204c494b1ed49e8c1d94429ea78b1)、[commit c7b793a](https://github.com/git/git/commit/c7b793a17d92350632c51a24e06b6a3dc4a93c2b)、[commit 80a6b3f](https://github.com/git/git/commit/80a6b3f0d54d0df6c6994df5486433bf0b9a54c0)、[commit 9375dcf](https://github.com/git/git/commit/9375dcf3b9bb1e462e28d5017165e1c7fa741c77)、[commit e74ef60](https://github.com/git/git/commit/e74ef604974192712c38f77cd751b00ad36e1378)、[commit 27fe43e](https://github.com/git/git/commit/27fe43e869f4ee8865beeedf6f2bbbab07cf0c7c)、[commit 2525c51](https://github.com/git/git/commit/2525c5170f1088dac0aeb18444041f9fff04761a)、[commit becd67f](https://github.com/git/git/commit/becd67fd281fa0efdf8f6346f311954a237dc991)、[commit a5c98ac](https://github.com/git/git/commit/a5c98acec6ad8e8c397b1001621a4edfacc98516)、[commit 8c311f9](https://github.com/git/git/commit/8c311f96a5a089d2f35654e9af7c44377a27839b)、[commit 57da049](https://github.com/git/git/commit/57da04965d56c7d7da6a00c3fb6fc3981cf0ba9a)、[commit 1d9e86f](https://github.com/git/git/commit/1d9e86f80d2ede6829c57ef4b22e4dd8b162cc7e)、[commit 78ba28d](https://github.com/git/git/commit/78ba28d84b5be8cbb1d5d5e7d65b5522739ad5ce)、[commit efa639f](https://github.com/git/git/commit/efa639fe6b850de699b675bf3e9c4b35f54f54bc)、[commit 1be2fa0](https://github.com/git/git/commit/1be2fa02b5ac97346e6745c767c559ee363ff378)、[commit 38e9476](https://github.com/git/git/commit/38e947660b2bb09e035f91b682b7011c2808052e),[commit 8823d2f](https://github.com/git/git/commit/8823d2fa792efbc89d3ab1392a4b064e8fbd6705),[commit 32858a0](https://github.com/git/git/commit/32858a01506b22963cfd5f8c8db95486f26133af),[commit cd914d8](https://github.com/git/git/commit/cd914d8090d64c8df1b0c45327de7dacdf370a09)(12 Jan 2016)by [Elia Pinto (
)](https://github.com/devzero2000) . (由[Junio C Hamano --
--](https://github.com/gitster)合并至[commit e572fef](https://github.com/git/git/commit/e572fef9d459497de2bd719747d5625a27c9b41d),2016年1月22日) 从Git 2.8开始,它都是
...
uxhixvfz4#
当使用旧的反勾形式时,反斜杠保留其字面意义,除非后跟$,或\。第一个不带反斜杠的反勾号终止命令替换。 当使用较新的$(command)`时,括号之间的所有字符组成命令;没有一个是特殊处理的。这两种形式都可以嵌套,但反勾号类型需要以下形式。
或\。第一个不带反斜杠的反勾号终止命令替换。 当使用较新的
`echo \`foo\``
相反:
$(echo $(foo))
oxf4rvwz5#
除了可以在命令中使用的非转义字符之外,几乎没有什么区别。您甚至可以将**...命令放在$(...)命令中(反之亦然),以实现更复杂的两级命令替换。对反斜杠字符/操作符的解释略有不同。除此之外,当嵌套...替换命令时,必须用\,转义内部的`字符,而用$()**替换它会自动理解嵌套。
eit6fx6z6#
“这两种方法有什么区别?”注意这种行为:
A="A_VARIABLE" echo "$(echo "\$A")" echo "`echo "\$A"`"
你会得到这些结果:
$A A_VARIABLE
zd287kbt7#
反引号和用于命令替换的较新的首选POSIX语法之间的一个新的区别是如何处理注解。反引号中的哈希字符创建了一个以第二个反引号字符结束的注解,有效地创建了一种具有中间行注解的方法。
$ echo "Goodbye` # Cruel` World" Goodbye World
使用较新的首选语法,注解将继续到行尾,因此命令必须分为两行:
$ echo "Goodbye$( # Cruel > ) World" Goodbye World
如果你试图在控制台的单行上输入它,你的终端只会换行:
$ echo "Goodbye$( # Cruel) World" >
但是,您可以通过将命令传递给sh -c将其强制为一行。然后你会看到它会导致一个语法错误:
sh -c
$ sh -c 'echo "Goodbye$( # Cruel) World"' sh: 1: Syntax error: end of file unexpected (expecting ")")
7条答案
按热度按时间j0pj023g1#
反引号/gravemark已经被弃用,而支持
$()
作为命令替换,因为$()
可以像$(echo foo$(echo bar))
一样轻松地嵌套在自己内部。还有其他的区别,比如反斜线在反勾号/gravemark版本中是如何解析的,等等。请参阅BashFAQ/082,了解始终首选$(...)语法的几个原因。
有关各种差异的详细信息,请参阅POSIX规范。
5sxhfpxr2#
他们的行为是一样的。区别在于语法:嵌套
$()
比嵌套````更容易:vs.
6qftjkof3#
2014年7月:commit f25f5e6(by Elia Pinto (
devzero2000
),April 2014,Git 2.0)增加了嵌套问题:反引号形式是命令替换的传统方法,并且由POSIX支持。
**然而,除了最简单的用法外,所有的用法都很快变得复杂。
特别是,嵌入式命令替换和/或双引号的使用需要小心地使用反斜杠字符**进行转义。
这就是为什么git/Documentation/CodingGuidelines提到:
我们更喜欢
$( ... )
作为命令替换;**不像,它正确地嵌套**。 伯恩从第一天起就应该这样拼写,但不幸的是不是。 [thiton](https://stackoverflow.com/users/847601/thiton)评论: 这就是为什么
echofoo```一般不工作的原因,因为每个````都可以打开或关闭,因此存在固有的模糊性。 它可能会因运气或特殊功能而适用于特殊情况。 2016年1月更新:Git 2.8(2016年3月)完全去除了反引号。 参见[commit ec1b763](https://github.com/git/git/commit/ec1b763d05bb03d8741c1363d7acf4ccb7153f6d)、[commit 9c10377](https://github.com/git/git/commit/9c1037751c0204c494b1ed49e8c1d94429ea78b1)、[commit c7b793a](https://github.com/git/git/commit/c7b793a17d92350632c51a24e06b6a3dc4a93c2b)、[commit 80a6b3f](https://github.com/git/git/commit/80a6b3f0d54d0df6c6994df5486433bf0b9a54c0)、[commit 9375dcf](https://github.com/git/git/commit/9375dcf3b9bb1e462e28d5017165e1c7fa741c77)、[commit e74ef60](https://github.com/git/git/commit/e74ef604974192712c38f77cd751b00ad36e1378)、[commit 27fe43e](https://github.com/git/git/commit/27fe43e869f4ee8865beeedf6f2bbbab07cf0c7c)、[commit 2525c51](https://github.com/git/git/commit/2525c5170f1088dac0aeb18444041f9fff04761a)、[commit becd67f](https://github.com/git/git/commit/becd67fd281fa0efdf8f6346f311954a237dc991)、[commit a5c98ac](https://github.com/git/git/commit/a5c98acec6ad8e8c397b1001621a4edfacc98516)、[commit 8c311f9](https://github.com/git/git/commit/8c311f96a5a089d2f35654e9af7c44377a27839b)、[commit 57da049](https://github.com/git/git/commit/57da04965d56c7d7da6a00c3fb6fc3981cf0ba9a)、[commit 1d9e86f](https://github.com/git/git/commit/1d9e86f80d2ede6829c57ef4b22e4dd8b162cc7e)、[commit 78ba28d](https://github.com/git/git/commit/78ba28d84b5be8cbb1d5d5e7d65b5522739ad5ce)、[commit efa639f](https://github.com/git/git/commit/efa639fe6b850de699b675bf3e9c4b35f54f54bc)、[commit 1be2fa0](https://github.com/git/git/commit/1be2fa02b5ac97346e6745c767c559ee363ff378)、[commit 38e9476](https://github.com/git/git/commit/38e947660b2bb09e035f91b682b7011c2808052e),[commit 8823d2f](https://github.com/git/git/commit/8823d2fa792efbc89d3ab1392a4b064e8fbd6705),[commit 32858a0](https://github.com/git/git/commit/32858a01506b22963cfd5f8c8db95486f26133af),[commit cd914d8](https://github.com/git/git/commit/cd914d8090d64c8df1b0c45327de7dacdf370a09)(12 Jan 2016)by [Elia Pinto (
devzero2000)](https://github.com/devzero2000) . (由[Junio C Hamano --
gitster--](https://github.com/gitster)合并至[commit e572fef](https://github.com/git/git/commit/e572fef9d459497de2bd719747d5625a27c9b41d),2016年1月22日) 从Git 2.8开始,它都是
$(...)`,不再是...
。uxhixvfz4#
当使用旧的反勾形式时,反斜杠保留其字面意义,除非后跟$,
或\。第一个不带反斜杠的反勾号终止命令替换。 当使用较新的
$(command)`时,括号之间的所有字符组成命令;没有一个是特殊处理的。这两种形式都可以嵌套,但反勾号类型需要以下形式。
相反:
oxf4rvwz5#
除了可以在命令中使用的非转义字符之外,几乎没有什么区别。您甚至可以将**
...
命令放在$(...)命令中(反之亦然),以实现更复杂的两级命令替换。对反斜杠字符/操作符的解释略有不同。除此之外,当嵌套
...
替换命令时,必须用\,转义内部的`字符,而用$()**替换它会自动理解嵌套。eit6fx6z6#
“这两种方法有什么区别?”
注意这种行为:
你会得到这些结果:
zd287kbt7#
反引号和用于命令替换的较新的首选POSIX语法之间的一个新的区别是如何处理注解。反引号中的哈希字符创建了一个以第二个反引号字符结束的注解,有效地创建了一种具有中间行注解的方法。
使用较新的首选语法,注解将继续到行尾,因此命令必须分为两行:
如果你试图在控制台的单行上输入它,你的终端只会换行:
但是,您可以通过将命令传递给
sh -c
将其强制为一行。然后你会看到它会导致一个语法错误: