Shell 分叉进程中的局部变量 linux

Shell local variable in forked process linux

我了解到分叉的子进程从父进程继承其环境(例如 env 变量)。也有人说局部 shell 变量对分叉的子进程不可用,但如果是这种情况,shell 中定义的局部变量如何被其子进程回显(echo in this案件)?因为 echo 是 shell.

的子进程

Child 进程获取其 parent 环境的副本。他们可以看到所有 exported 环境变量,甚至可以修改它们,但是 parent.

看不到这些修改

parent 中设置的变量在 child 中可见:

$ export foo=bar
$ echo "parent: $foo"
parent: bar
$ (echo "child: $foo")
child: bar

child 中的修改在 parent 中不可见:

$ (foo=baz; echo "child: $foo")
child: baz
$ echo "parent: $foo"
parent: bar

如果您没有 export 变量,那么它只是一个 shell 变量,而不是环境的一部分。在那种情况下,您可以在 subshell 中看到变量,因为 subshell 是特殊情况:

$ foo=bar
$ (echo "child: $foo")
child: bar

然而,如果您通过任何其他机制创建一个 child 进程,例如通过显式调用 bash,它将不可见,因为它不是环境的一部分并且不会存在叉子:

$ foo=bar
$ bash -c 'echo "child: $foo"'
child: 

I have read that a forked child process gets its environment (such as env variables) inherited from the parent process.

不是“例如”。在“环境”这个词的意义上,环境仅由环境变量名称和值组成。每个进程都有一个更大、更具包容性的执行上下文,但它的“环境”只是一组变量。

It is also said that local shell variables are not available to the forked child processes

您在评论中澄清了“本地 shell 变量”是指未标记为导出的变量。是的,根据定义,这些不提供给子进程。

if that is the case how can a local variable defined in a shell be echoed by its child process (echo in this case)? as echo is the child process of the shell.

它不能也不会,因为echo不会那样做。我的意思是,它对从其父进程继承的任何环境变量没有任何作用。

我想你一定是在问这样的问题:

# not exported:
foo=something

echo "$foo"

,它将打印“something”后跟一个换行符。但这并不依赖于将变量 foo 导出到运行 echo 的进程。相反,shell 将变量引用扩展为更大的扩展集合的一部分,它在执行每个命令之前对其执行。子进程接收文字 something 作为其参数。

要进一步阐明,试试这个:

foo=something

bash -c "echo $foo"
bash -c 'echo $foo'

输出是一个“东西”和一个空行。为什么?因为父 shell 扩展了双引号内的变量引用,而不是单引号内的变量引用。在这两种情况下,子 bash 进程都不会在其环境中接收到变量 foo,但在第一种情况下它不需要它,因为在该进程接收到它时,命令字符串被要求execute 没有引用 $foo。第二种情况就不一样了。