shell 创建将执行命令的子进程之前或之后是否添加了临时环境变量?

shell 创建将执行命令的子进程之前或之后是否添加了临时环境变量?

在 bash 中,运行时

myvar=val mycommand myargs

myvar=val将被添加到执行环境中mycommand

假设bash进程调用fork()创建一个将执行的子进程mycommand,即mycommand外部可执行文件或脚本文件。

何时添加myvar=val到环境中,在 bash shell 调用之前还是之后fork()?换句话说,以下两种可能性中的哪一种实际上发生了?

  • bash进程添加myvar=val 到自己的环境中,然后调用fork()创建一个子进程,该子进程将调用execve()execute mycommand,并且myvar=val作为bash进程环境的一部分被继承到子进程的环境中。当mycommand子进程执行完毕并退出后,bash 进程就会myvar=val从它自己的环境中退出。

  • bash进程调用fork()创建一个将执行的子进程mycommand,子进程添加myvar=val到自己的环境中,然后调用execve()execute mycommand

我的问题的动机来自斯蒂芬对我之前帖子的回复

在巴什中,_是一个特殊参数,每次解析命令时都会将其设置为最后一个参数的值。它还具有不可导出的特殊属性,每次执行命令时都会强制执行该属性(请参阅bind_lastarg在 Bash 源代码中)。

我想知道当bash进程执行命令时,如果bash没有添加_到自己的环境中,为什么需要将其从自己的环境中删除?

谢谢。

答案1

现实情况介于您描述的两种可能性之间。 Bash 并没有添加myvar自己的环境,至少不是我们通常认为的完整的 shell 环境;它补充说myvar它的暂时的环境。然后,它从临时环境以及当前变量上下文和 shell 函数构建导出环境,特别是新命令,如果需要运行子命令,则分叉。您可以将其视为打电话给maybe_make_export_envBash 源代码中的。孩子启动后,再清理临时环境;寻找dispose_used_env_vars

实际上这没有任何区别。子命令获取它应该接收的环境,一旦您重新获得控制权,父环境也应该处于该状态;除非您要对 Bash 进行更改,否则这才是最重要的。

相关内容