引自维基百科:
默认情况下,当创建一个进程时,它会继承其父进程的重复环境,除了父级在创建子级时所做的显式更改之外。在 API 级别,这些更改必须在 fork 和 exec 之间完成。或者,从 bash 等 shell 中,您可以通过 env 间接调用特定命令调用或使用 ENVIRONMENT_VARIABLE=VALUE 表示法来更改特定命令调用的环境变量。
我理解“当创建一个进程时,它会继承其父进程的重复环境”。但我想知道例外“父级在创建子级时所做的显式更改”的真正含义是什么?我不明白 API 和 shell 中的示例如何成为异常的示例。
答案1
在 UNIX 模型中,启动另一个程序涉及两个原语:
fork()
创建调用进程的(几乎)相同的副本。新进程称为子进程,原进程称为父进程。子进程运行与原始进程相同的代码,具有相同的权限,具有相同的环境,并接收父进程的可变数据内存的副本。两个进程之间最明显的区别是它们具有不同的进程 ID 和不同的父进程 ID(子进程的 PPID 是父进程的 PID)。execve()
用从可执行文件加载的代码和数据替换当前进程的代码和数据。该系统调用将进程的新环境作为参数。
大多数高级函数都是围绕进程的当前环境构建的fork()
,并将其传递给.因此,除非进程改变自己的环境或直接调用,否则被调用程序将继承调用程序的环境。execve()
execve()
execve()
Shell 通常将其环境传递给它们调用的程序。您可以随时通过为环境变量赋值来更改 shell 的环境(foo="some value"
;如果该变量不在环境中,则必须调用export foo
),或者通过取消设置来从环境中删除变量 ( unset foo
)。如果您想使用不同或附加的环境变量启动外部程序,可以使用快捷语法:
foo="some value" mycommand
大致相当于
(foo="some value"; export foo; exec mycommand)
(其中括号限制 的设置范围foo
)。
答案2
API 指的是exec
C
用于执行另一个进程的函数系列。
一个进程启动另一个进程的典型顺序是首先fork
,然后在刚刚创建的子级中,调用其中一个exec
函数。
在 和 之间fork
,exec
在子进程中,可以在启动目标可执行文件之前更改环境。
并且execle
还execvpe
允许调用进程直接传入目标环境。
如果未使用execle
和execvpe
,并且在对子级的调用fork
和exec
子级中的调用之间没有修改环境,则应用正常规则。
shell 示例旨在向您展示如何更改 shell 子级的环境。如果 shell 没有使用上述一些“技巧”,它就不能让您这样做 - 所有子进程都将获得当前 shell 环境的精确副本。