Bash 中执行的新进程如何始终具有相同的环境变量?

Bash 中执行的新进程如何始终具有相同的环境变量?

不久前,我正在使用 GDB 探索一个简单的 C 程序的 ELF 二进制文件。我看到printenv在终端中运行时打印的环境变量也出现在我在该终端中运行的 C 程序二进制文件的堆栈顶部。

Bash 是如何实际执行程序并同时将所有环境变量添加到新进程的堆栈中的?简而言之,当我运行这样的程序时,一步一步会发生什么: ./myprogram

答案1

Linux 程序是通过execve系统调用来执行的。execve有以下签名:

int execve(const char *filename, char *const argv[], char *const envp[]);

最后一个参数envp,用于将环境作为字符串数组传递给进程,每个字符串的形式为 key=value。按照惯例,相同的环境会从一个进程传递到另一个进程,除非调用进程对其进行一些更改。内核安排新程序接收堆栈上的环境,就像传递程序参数一样。

库函数execlexeclpexecvexecvp不带参数envp(但execleexecvpe函数带参数)。这些函数从environ调用过程中的全局变量获取环境。这样,使用该execle函数启动另一个程序的程序就不必担心传递环境,但库函数会自动“在幕后”执行此操作。

所有提到的库函数最终都会调用execve系统调用,并在参数中传递环境envp

相关内容