什么是 shell 中的命令替换?

use*_*970 11 command-substitution

我正在将 Ubuntu 16.04 与 Bash 一起使用,我尝试在Wikipedia中阅读此处和此处,但我无法理解一般 shell 脚本中“命令替换”的含义,特别是在 Bash 中,如下所示:

$(command)
Run Code Online (Sandbox Code Playgroud)

或者

`command`
Run Code Online (Sandbox Code Playgroud)

这个词的含义是什么?

编辑:当我第一次发布这个问题时,我已经知道替换的纯概念以及变量替换的 Linux 概念(通过执行替换变量的值),但我仍然从文档中错过了这个 shell 特性的目的原因或原因组。


问题锁定后我的回答

命令替换是一种具有专用语法的操作,用于执行命令并将该命令的输出保存(存储)在变量中以备后用。

一个例子date:

thedate="$(date)"
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用以下命令打印结果printf:

printf 'The date is %s\n' "$thedate"
Run Code Online (Sandbox Code Playgroud)
  1. 命令替换语法是$().
  2. 命令本身是date.
  3. 结合我们得到的$(date),它的值是替换的结果(我们可以在执行后得到)。
  4. 我们将该值保存在变量 中$thedate以备后用。
  5. printf根据上面的命令,我们使用 , 显示变量保存的输出值。

注意:\ninprintf是换行符。

Kus*_*nda 19

“命令替换”是 shell 语言功能的名称,它允许您执行命令并让该命令的输出替换(替换)命令的文本。

shell 语言没有其他功能可以让您这样做。

命令替换,即整个$(...)表达式,被其输出替换,这是命令替换的主要用途。

命令替换执行的命令在子shell中执行,这意味着它有自己的环境,不会影响父shell的环境。

不过,并非所有子 shell 执行都是命令替换(请参阅最后的更多示例)。

显示在子 shell 中执行命令替换的示例:

$ s=123
$ echo "hello $( s=world; echo "$s" )"
hello world
$ echo "$s"
123
Run Code Online (Sandbox Code Playgroud)

在这里,变量s设置为 string 123。在下一行,echo在包含命令替换结果的字符串上调用。命令替换设置s为字符串world并回显该字符串。该字符串world是命令替换中命令的输出,因此,如果在 下运行set -x,我们将看到上面的第二行将被扩展为echo 'hello world',这将hello world在终端上生成:

$ set -x
$ echo "hello $( s=world; echo "$s" )"
++ s=world
++ echo world
+ echo 'hello world'
hello world
Run Code Online (Sandbox Code Playgroud)

(在跟踪输出中的命令替换子shell的每一级bash添加额外级别的+提示,其他shell可能不会这样做)

最后,我们展示了命令替换中的命令是在它自己的子 shell 中运行的,因为它不会影响s调用 shell 中 的值(的值s仍然是123,不是world)。

在子shell中执行命令还有其他情况,例如

echo 'hello' | read message
Run Code Online (Sandbox Code Playgroud)

在 中bash,除非您设置该lastpipe选项(仅在非交互式实例中),否则将read在子 shell 中执行,这意味着$message不会在父 shell 中更改,即echo "$message"在上述命令之后执行将回显空字符串(或任何值)$message之前)。

进程替换bash也在子shell中执行:

cat < <( echo 'hello world' )
Run Code Online (Sandbox Code Playgroud)

这也不同于命令替换。