命令替换子 shell 中的 bash 变量可见性

命令替换子 shell 中的 bash 变量可见性

我正在阅读一本 Linux shell 脚本编写书籍,发现以下警告:

“命令替换创建所谓的子 shell 来运行所包含的命令。子 shell 是从运行脚本的 shell 生成的单独子 shell。因此,您在脚本中创建的任何变量都不可用于 subshel​​l 命令”。

我尝试在当前 bash shell 的 CLI 中创建一个变量,然后进入子 shell 检查是否可以在屏幕上打印它。所以是的,我做不到,似乎是根据上面的引文。但是,我已经通过命令替换运行了以下脚本:

#!/bin/bash
var=5.5555
ans=$(echo $var)
echo $ans

结果是:

5.5555

据我了解,它不应该打印 var 的值,因为子 shell 不应该能够“看到它”。为什么会发生这种情况?

答案1

该声明:

因此,您在脚本中创建的任何变量都不可用于 subshel​​l 命令。

是假的。父 shell 中定义的变量的范围是整个脚本(包括通过命令替换创建的子 shell)。

跑步:

#!/bin/bash
var=5.5555
ans1=$(echo $var)
ans2=$(var=6; echo $var)
echo $ans1
echo $ans2

将给出结果:

5.5555
6

$var由子shell解决:

  • 如果没有指定局部变量,则使用三个全局变量的值
  • 如果指定了局部变量,则它使用它的值

另请参阅示例21-2

答案2

所引用的说法并不属实。在子 shell 运行之前变量已被预先替换也是不正确的。

您可以直接使用来验证这一点变量间接

$ x=hello
$ echo Result is $(y=x ; echo ${!y} ; echo world)
Result is hello world

该变量x绝对可以直接供子 shell 使用(而不是先前扩展其值),因为${!y}从变量中读取姓名存储在y- 创建子 shell 时不存在。


对书中这段话的宽容解读是,它的意思是说“变量”不可用,因为你无法持久地修改它的值。您在子 shell 中进行的任何变量分配随后都不可用于父 shell,无论是创建新变量(如y)还是将替换值分配给现有变量。如果将子 shell 分配给x,则新值将在子 shell 内生效,但随后从中读取将给出原始值:

$ x=world
$ echo $(x=hello ; echo $x)
hello
$ echo $x
world

至少在您引用的段落中,这不是一种非常清晰的表达方式。如果整本书都是这样,你也许可以找到一本更好的书(或者阅读这里的问题)。

相关内容