从https://unix.stackexchange.com/a/436631/674
文件
/proc/$$/environ
...不反映环境的任何更改,而只是报告程序在被exec
进程编辑时收到的内容。
来自APUE:
每个程序还传递一个环境列表。与参数列表一样,环境列表是一个字符指针数组,每个指针都包含以 null 结尾的 C 字符串的地址。指针数组的地址包含在全局变量中
environ
:extern char **environ;
访问特定环境变量通常是通过
getenv
和putenv
函数(如第 7.9 节中所述),而不是通过环境变量。但要遍历整个环境,environ
就必须使用指针。
/proc/$$/environ
和全局变量是environ
相互独立还是一致?
通过 访问的字符串是否environ
也不反映环境的任何更改,而只是报告通过 接收的环境 execve()
?
或者通过访问的字符串是否environ
始终反映对它们的任何更改,就像总是getenv
获取最新的环境字符串一样?
通过访问的字符串是否 getenv
始终反映任何更改并且始终是最新的?
谢谢。
答案1
/proc/$$/environ
并且变量environ
是独立的。确实反映了环境的变化,事实上,当环境变量通过via添加到环境中时,environ
指针的值也会变化(但这是一个实现细节。)environ
putenv()
我们必须区分系统调用级别和库级别。在系统调用级别,与环境相关的唯一机制是调用envp
的参数execve
。该参数预计包含name=value
构成新程序环境的对。该环境被复制到新进程的堆栈中,用户空间启动代码可以在其中拾取它。
在图书馆层面,我们有
- 全局变量
environ
,它指向环境的副本 - 功能
getenv()
以及putenv()
检查和修改环境 - 隐式(通过)或显式(通过参数传递)访问环境的
exec*
函数系列(不包括)execve
environ
库exec*
函数最终调用的是execve
系统调用。该environ
变量不指向堆栈上的环境;相反,在environ
设置变量之前将环境复制到进程堆(这又是一个实现细节。)
为什么不/proc/$$/environ
反映环境的变化?/proc/$$/environ
是内核提供的虚拟文件,内核无法知道用户进程中地址空间的低层发生了什么。内核不知道该environ
变量,也不知道进程用来存储环境的数据结构。