在 bash 中,运行时
myvar=val mycommand myargs
myvar=val
将被添加到执行环境中mycommand
。
假设bash进程调用fork()
创建一个将执行的子进程mycommand
,即mycommand
外部可执行文件或脚本文件。
何时添加myvar=val
到环境中,在 bash shell 调用之前还是之后fork()
?换句话说,以下两种可能性中的哪一种实际上发生了?
bash进程添加
myvar=val
到自己的环境中,然后调用fork()
创建一个子进程,该子进程将调用execve()
executemycommand
,并且myvar=val
作为bash进程环境的一部分被继承到子进程的环境中。当mycommand
子进程执行完毕并退出后,bash 进程就会myvar=val
从它自己的环境中退出。bash进程调用
fork()
创建一个将执行的子进程mycommand
,子进程添加myvar=val
到自己的环境中,然后调用execve()
executemycommand
。
我的问题的动机来自斯蒂芬对我之前帖子的回复。
在巴什中,
_
是一个特殊参数,每次解析命令时都会将其设置为最后一个参数的值。它还具有不可导出的特殊属性,每次执行命令时都会强制执行该属性(请参阅bind_lastarg
在 Bash 源代码中)。
我想知道当bash进程执行命令时,如果bash没有添加_
到自己的环境中,为什么需要将其从自己的环境中删除?
谢谢。
答案1
现实情况介于您描述的两种可能性之间。 Bash 并没有添加myvar
自己的环境,至少不是我们通常认为的完整的 shell 环境;它补充说myvar
它的暂时的环境。然后,它从临时环境以及当前变量上下文和 shell 函数构建导出环境,特别是新命令,前如果需要运行子命令,则分叉。您可以将其视为打电话给maybe_make_export_env
Bash 源代码中的。孩子启动后,再清理临时环境;寻找dispose_used_env_vars
。
实际上这没有任何区别。子命令获取它应该接收的环境,一旦您重新获得控制权,父环境也应该处于该状态;除非您要对 Bash 进行更改,否则这才是最重要的。