当我们将命令放在美元符号和括号内时,shell 中的含义是啥: $(command)

Posted

技术标签:

【中文标题】当我们将命令放在美元符号和括号内时,shell 中的含义是啥: $(command)【英文标题】:What does it mean in shell when we put a command inside dollar sign and parentheses: $(command)当我们将命令放在美元符号和括号内时,shell 中的含义是什么: $(command) 【发布时间】:2013-08-01 20:08:14 【问题描述】:

我只想了解 shell 中的以下代码行。它用于获取当前工作目录。我知道 $(variable) 名称返回变量名称中的值,但 $(command) 应该返回什么?执行命令后是否返回值?在这种情况下,我们可以使用` 来执行命令。

CWD="$(cd "$(dirname $0)"; pwd)"

在不同版本的shell中也可以从以下代码行中获取相同的输出

DIR="$( cd "$( dirname "$BASH_SOURCE[0]" )" && pwd )"

我无法理解$(cd..$(dirname 的含义。

谁能帮我弄清楚这个命令是如何执行的?

【问题讨论】:

这是一个关于$()``的优缺点的问题:***.com/questions/9449778/… 【参考方案1】:

$$HOME 的使用给出了 HOME 的值。像$(echo foo) 一样使用$ 意味着运行子shell 中括号内的任何内容并将其作为值返回。在我的示例中,您会得到 foo,因为 echo 会将 foo 写入标准输出

【讨论】:

是的; $(...) 是一种比尝试使用反引号更好的方法来编写命令。考虑写:gcclib=$(dirname $(dirname $(which gcc)))/lib 使用反引号。甚至在您遇到在 Markdown 中执行此操作的困难之前,它就更难了,因为您必须转义嵌套命令的反引号,而 $(...) 符号则不需要。 技术上,$(echo foo) 创建一个命令替换,而不是一个子shell。当前的另一个答案是正确的。我认为命令替换是在子 shell 中运行的,但它们仍然是不同的概念。 @trysis - 命令替换definitely runs in a subshell,所以值得注意。 我知道反引号产生与 $() 相同的结果,但区别纯粹是装饰性的吗?除了 $() 更易读之外,是否有理由使用一个与另一个? “像 $(echo foo) 这样使用 $ 意味着在子 shell 中运行括号内的任何内容并将其作为值返回。”...这令人困惑,因为此命令$(echo foo) 将尝试运行括号中返回的内容,它将首先运行echo foo,然后尝试运行foo,这会给出错误【参考方案2】:
DIR="$( cd "$( dirname "$BASH_SOURCE[0]" )" && pwd )"

谁能帮我弄清楚这个命令是如何执行的?

让我们看看命令的不同部分。 BASH_SOURCE 是一个包含源文件名的 bash 数组变量。所以"$BASH_SOURCE[0]" 会返回脚本文件的名称。

dirname 是 GNU coreutils 提供的一个实用程序,用于从文件名中删除 最后一个组件。因此,如果您通过说bash foo 执行脚本,"$( dirname "$BASH_SOURCE[0]" )" 将返回.。如果你说bash ../foo,它会返回..;对于bash /some/path/foo,它会返回/some/path

最后,整个命令"$( cd "$( dirname "$BASH_SOURCE[0]" )" && pwd )" 得到包含被调用脚本的绝对目录。

$(...) 允许命令替换,即允许命令的输出替换命令本身并且可以嵌套。

【讨论】:

很抱歉迟到了 3 年,但您能否解释一下为什么该声明有效?你说dirname返回执行文件的路径(相对于当前工作目录或绝对路径),cd将密码更改为该目录,pwd打印出当前工作目录的绝对路径。但是为什么&& 会加入他们呢?如果cd 失败,DIR 会保留什么? @Christian, &&cd 失败时阻止pwd 运行,这样DIR 将是空的,而不是目录不正确。

以上是关于当我们将命令放在美元符号和括号内时,shell 中的含义是啥: $(command)的主要内容,如果未能解决你的问题,请参考以下文章

shell中规则表达式与特殊符号

shell脚本中常见的一些特殊符号和作用详解

SHELL笔记4

shell之小括号中括号大括号

shell脚本变量数值计算

Linux Shell 几个特殊符号命令 & && ||