当我们在美元符号和括号中放入一个命令时,它在shell中意味着什么:$(command)

KIt*_*tis 97 bash shell terminal ksh sh

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

CWD="$(cd "$(dirname $0)"; pwd)"
Run Code Online (Sandbox Code Playgroud)

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

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Run Code Online (Sandbox Code Playgroud)

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

有人可以帮我弄清楚这个命令是如何执行的吗?

Eri*_*ban 104

使用之$${HOME}给出了HOME的价值.使用$类似$(echo foo)意味着运行子shell中括号内的任何内容并将其作为值返回.在我的例子,你会得到foo,因为echo会写foo到标准输出

  • 是; `$(...)`是一种更好的编写命令的方法,而不是试图使用后引号.考虑使用后引号写:`gcclib = $(dirname $(dirname $(gcc)))/ lib`.甚至在你遇到在Markdown中执行它的困难之前,它就更难了,因为你必须逃避嵌套命令的反引号,而你却不使用`$(...)`符号. (35认同)
  • 同样的事情是由``echo foo \`完成的,我是对的吗? (12认同)
  • 从技术上讲,`$(echo foo)`创建一个命令替换,而不是子shell.另一个当前的答案是正确的.我认为命令替换是在子shell中运行的,但它们仍然是不同的概念. (7认同)
  • *“像 $(echo foo) 这样的 $ 的使用意味着在子 shell 中运行括号内的任何内容并将其作为值返回。”*...这令人困惑,因为这个命令 `$(echo foo)` 将尝试**运行括号中返回的内容**,它将首先运行`echo foo`,然后尝试运行`foo`,这会产生错误 (3认同)
  • @trysis-命令替换[**绝对**在子外壳中运行](https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html),因此值得一提。 (2认同)
  • 我知道反引号产生与$()相同的结果,但纯粹是装饰性的区别?是否有理由使用一个与另一个,除了$()更清晰? (2认同)

dev*_*ull 20

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Run Code Online (Sandbox Code Playgroud)

有人可以帮我弄清楚这个命令是如何执行的吗?

让我们看一下命令的不同部分.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 )"获取包含被调用脚本的绝对目录.

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

  • @ Christian,`&&`会在cd失败的情况下阻止pwd的运行,从而使DIR为空而不是目录不正确。 (2认同)