Shell 分叉进程中的局部变量 linux
Shell local variable in forked process linux
我了解到分叉的子进程从父进程继承其环境(例如 env 变量)。也有人说局部 shell 变量对分叉的子进程不可用,但如果是这种情况,shell 中定义的局部变量如何被其子进程回显(echo in this案件)?因为 echo 是 shell.
的子进程
Child 进程获取其 parent 环境的副本。他们可以看到所有 export
ed 环境变量,甚至可以修改它们,但是 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
。第二种情况就不一样了。
我了解到分叉的子进程从父进程继承其环境(例如 env 变量)。也有人说局部 shell 变量对分叉的子进程不可用,但如果是这种情况,shell 中定义的局部变量如何被其子进程回显(echo in this案件)?因为 echo 是 shell.
的子进程Child 进程获取其 parent 环境的副本。他们可以看到所有 export
ed 环境变量,甚至可以修改它们,但是 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
。第二种情况就不一样了。