流程'环境变量的当前值

时间:2012-11-03 13:52:16

标签: bash unix process procfs

我想知道是否有办法从bash进程设置环境变量并从另一个进程读取它。

由于环境变量的值是进程的本地值(除继承之外),因此不能只在终端中执行export FOO="bar"并从另一个终端读取它。 然后我试图让他们通过/proc/environ,但这就是我得到的:

etuardu@subranu:~$ FOO="foo" bash
etuardu@subranu:~$ strings /proc/$$/environ | grep FOO
FOO=foo
etuardu@subranu:~$ export FOO="bar"
etuardu@subranu:~$ strings /proc/$$/environ | grep FOO
FOO=foo
etuardu@subranu:~$ echo $FOO
bar

似乎我可以获得该过程开始时该环境变量的值 它的当前价值如何?

1 个答案:

答案 0 :(得分:6)

由于环境变量的工作方式,这通常是不可能的。

当一个进程第一次exec时,内核为它提供了一组初始环境变量以及其他一些东西(主要是它的argv向量,即它的命令行)。此后,此列表(如argv向量)只是进程内的常规C字符指针数组。这个过程可以随意管理它们,包括完全回收存储字符串的内存以供其他用途使用。一个进程在任何其他进程的内存空间内窥视以查找其环境变量是不安全的。

大多数类型的进程确实使用内核提供的环境变量列表或多或少,可能是查询它并使用getenv()putenv()等C库函数对其进行修改。如果这些进程依次运行任何其他可执行文件,它们会将相同的环境向量传递给它们在自己执行开始时收到的execve系统调用,这意味着新的可执行文件获得相同的环境(可能已增强)通过调用putenv())。

贝壳是另一回事。由于环境变量在shell脚本中非常重要,因此一些shell仅将提供给它们的环境向量用作“起始值”,然后忽略它。他们使用自己的,更强大的数据结构来管理他们的环境变量。当他们执行自己的子进程时,他们将一个全新的环境向量传递给新进程,从这些内部数据结构构建。这意味着即使您要查看shell的内存空间以找到上面建议的环境变量,您也只能找到初始集,而不是shell实际使用的环境!

可能能够做的是查询进程的初始环境变量集,即在启动时传递给可执行文件的相同向量。但这不是便携式的,即使在支持此功能的操作系统中也存在相当大的差异。例如,在历史上的UNIX中,它仍然有点难看,因为它仍然涉及窥视进程的内存空间(尽管是一个称为“用户区”的特殊内存区域)。 Linux使这一点变得更加优雅:可以在/proc/<pid>/environ中找到矢量作为文本字符串。在大多数可以获取此信息的系统上,ps都有一个e选项,可以显示该信息。