$() 是子 shell 吗?

$() 是子 shell 吗?

我理解子 shell 语法是(<commands...>)$()只是一个可以从中检索变量值的子 shell?

注意:这适用于 bash 4.4,基于其文档中的不同措辞。

答案1

$(…)根据定义,它是一个子 shell:它是 shell 运行时状态的副本,并且在子 shell 中对状态进行的更改不会对父 shell 产生影响。子shell通常由以下方式实现分叉一个新的进程(但某些 shell 在某些情况下可能会对此进行优化)。

它不是您可以从中检索变量值的子 shell。如果变量的更改对父级产生影响,则它不会是子 shell。这是一个子shell,其输出家长可以检索。创建的子 shell$(…)将其标准输出设置为管道,父 shell 从该管道读取并收集输出。

还有其他几种创建子 shell 的结构。我认为这是 bash 的完整列表:

  • 子外壳为分组( … )除了创建一个子 shell 并等待它终止之外什么也不做)。与{ … }哪些组命令纯粹出于语法目的并且不创建子 shell 进行对比。
  • 背景… &创建一个子shell并且不等待它终止。
  • 管道… | …创建两个子 shell,一个用于左侧,一个用于右侧,并等待两个子 shell 都终止。 shell 创建一个管道,并将左侧的标准输出连接到管道的写入端,将右侧的标准输入连接到读取端。在某些 shell 中(ksh88、ksh93、zsh、bash 以及lastpipe选项设置且有效),右侧在原始 shell 中运行,因此管道构造仅创建一个子 shell。
  • 命令替换: $(…)(也拼写为`…`)创建一个子 shell,其标准输出设置为管道,收集父级中的输出并扩展到该输出,减去其尾随换行符。 (输出可能会进一步受到分裂和通配的影响,但那是另一个故事了。)
  • 工艺替代<(…)创建一个子 shell,其标准输出设置为管道并扩展为管道的名称。父进程(或其他进程)可以打开管道与子 shell 进行通信。>(…)执行相同的操作,但使用标准输入上的管道。
  • 协同处理coproc …创建一个子shell并且不等待它终止。子 shell 的标准输入和输出均设置为一个管道,父级连接到每个管道的另一端。

^ 与运行单独的 shell 不同

答案2

从 bash 版本 4.4 中的 bash(1) 手册页,“扩展”部分,“命令替换”小节:

commandBash 通过在子 shell 环境中执行来执行扩展[...]

答案3

是的,( commands... )是一个bashcommands...在另一个进程中执行的子 shell。

唯一的区别$( commands... )是,这部分代码在执行后将被commands...写入.commands...stdout

相关内容