首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash嵌套子subshell参数展开

Bash嵌套子subshell参数展开
EN

Stack Overflow用户
提问于 2018-08-15 05:02:23
回答 1查看 1.8K关注 0票数 0

为什么$bar在这里被打印为文字,即使外部子subshell应该根据bash命令行处理规则展开它的参数?

代码语言:javascript
复制
$ foo='$bar' bar=expanded
$ echo $(echo $(echo $foo))
$bar

内部子外壳打印$bar,但是为什么外部子subshell不扩展它?bash是否隐式地将其作为文字传递,如果是,为什么以及如何传递?据我所知,参数展开发生在子subshell的每个分叉之后,在新进程中。在嵌套子shell的情况下,命令替换是从内到外执行的,内部子shell在发生分叉之前打印出外部shell命令行的文字、原始文本表示,命令行(字符串)正在由新shell进行拆分、扩展和处理。现在的问题是,为什么文本$bar不在外部子subshell中展开,即使它实际上不包含引号?为什么在这里隐式引用?

下面是没有嵌套shell的相同逻辑和预期输出的示例

代码语言:javascript
复制
$ foo='$bar' bar=expanded
$ echo $foo
$bar
$ echo $bar
expanded

另外,通过添加eval,我得到了我在第一个示例中所期望的结果,但我不明白为什么需要它,以及它是如何唤醒的。

代码语言:javascript
复制
$ echo $(eval echo $(echo $foo))
expanded
EN

回答 1

Stack Overflow用户

发布于 2018-08-15 06:44:09

巴什手册解释了有序的shell展开:(为清晰而重新格式化)

扩展的顺序是:

  • 支撑扩张;
  • tilde展开、参数和变量展开、算术扩展和命令替换(从左到右完成);
  • 分词;
  • 和文件名扩展。

在能够支持它的系统上,还有一个额外的扩展:进程替换。这是同时执行的倾斜,参数,变量,算术扩展和命令替换。

在执行这些扩展之后,将移除原始单词中的引号字符,除非它们本身已被引用(引用移除)。

这本质上是通过添加一些bash特定的扩展来响应Posix外壳规范的。

请注意,包含命令替换($(...))的第二组展开只执行一次,即从左到右。它们不会重复执行,因此命令替换的结果不受参数扩展的限制。除非引用,否则将受到分字、文件名扩展和引号删除的限制.

在子apply中计算的命令确实是由内到外计算的,但在每个级别上,内部命令替换只受分字、文件名展开和引号删除的限制(在本例中不适用)。

因此,所做的唯一的参数扩展是用它的值替换$foo

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51853204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档