在bash中有两种方法来捕获命令行的输出:

Legacy Bourne shell反引号' ': var =“命令” $()语法(据我所知是Bash特定的,或者至少不支持非posix旧shell,如原始Bourne) var = $(命令)

与反撇号相比,使用第二种语法有什么好处吗?还是两者完全相同?


当前回答

我想出了一个完全有效的$(…)除以'…'的例子。

我正在使用一个运行Cygwin的Windows远程桌面,并希望迭代一个命令的结果。遗憾的是,由于远程桌面或Cygwin本身的原因,反勾字符无法输入。

合理的假设是,在这种奇怪的设置中,美元符号和圆括号会更容易输入。

其他回答

来自man bash:

       $(command)
or
       `command`

Bash performs the expansion by executing command and replacing the com-
mand  substitution  with  the  standard output of the command, with any
trailing newlines deleted.  Embedded newlines are not deleted, but they
may  be  removed during word splitting.  The command substitution $(cat
file) can be replaced by the equivalent but faster $(< file).

When the old-style backquote form of substitution  is  used,  backslash
retains  its  literal  meaning except when followed by $, `, or \.  The
first backquote not preceded by a backslash terminates the command sub-
stitution.   When using the $(command) form, all characters between the
parentheses make up the command; none are treated specially.

在2021年,有必要提到一个奇怪的事实,作为对其他答案的补充。

Microsoft DevOps YAML管道“脚本”可能包含Bash任务。但是,符号$()用于引用YAML上下文中定义的变量,因此在这种情况下,应该使用反引号来捕获命令的输出。

在将脚本代码复制到YAML脚本时,这主要是一个问题,因为DevOps预处理器对不存在的变量非常宽容,所以不会出现任何错误消息。

我想出了一个完全有效的$(…)除以'…'的例子。

我正在使用一个运行Cygwin的Windows远程桌面,并希望迭代一个命令的结果。遗憾的是,由于远程桌面或Cygwin本身的原因,反勾字符无法输入。

合理的假设是,在这种奇怪的设置中,美元符号和圆括号会更容易输入。

$()允许嵌套。

out=$(echo today is $(date))

我觉得倒勾是不允许的。

最主要的一个是嵌套它们的能力,命令中的命令,而不会失去理智,试图弄清楚某种形式的转义是否对反节拍有效。

一个例子,虽然有点做作:

deps=$(find /dir -name $(ls -1tr 201112[0-9][0-9]*.txt | tail -1l) -print)

它会给你一个/dir目录树中所有与2011年12月以来最早的文本文件同名的文件的列表(a)。

另一个例子是获取父目录的名称(而不是完整路径):

pax> cd /home/pax/xyzzy/plugh
pax> parent=$(basename $(dirname $PWD))
pax> echo $parent
xyzzy

(a)既然那个特定的命令可能实际上不起作用,我还没有测试它的功能。所以,如果你投我的反对票,你已经失去了意图:-)这只是一个说明你如何嵌套,而不是作为一个没有bug的生产准备片段。