进程当前的环境变量

进程当前的环境变量

这个问题涉及到这个答案

是否可以通过创建子进程并检查其初始环境变量来获取进程的当前(非初始)环境变量?

这个想法是子进程的初始环境继承自父进程的当前环境。

答案1

环境是沿着系统调用传递的字符串列表execve,就像参数列表一样。时期。应用程序如何处理它收到的字符串列表取决于应用程序。

现在,按照惯例,该列表的使用方式通常与参数列表不同。程序通常会记住它们接收到的环境变量列表,并在执行另一个命令时重复使用相同的环境变量。

他们有 C 库函数来帮助他们做到这一点:环境作为变量提供,您可以使用、、 和 等函数检索environ和修改该列表(它收到的环境变量列表的副本)getenv,, , ...在执行命令时使用该变量(使用他们正在跟踪的变量进行调用)。setenvputenvexecvpexeclsystempopenenvironexecveenviron

现在应用程序不必使用该 API。他们可以使用自己的方式来管理环境变量列表。例如,Shell 将环境变量映射到 shell 变量,并且可能不使用 putenv/setenv libc 函数。perl有它的%ENV关联数组等等。

您始终可以使用gdb附加到进程并使其调用system("env > /tmp/some-file")(假设它们动态链接到 libc),但是如果您附加到的命令,您不能保证env将获得与另一个命令相同的环境以自己的方式执行它(例如,考虑 shell)。 (另请注意,system()启动 shell(解释命令行),并且 shell 可能会在启动时更改其环境(例如尝试env -i sh -c env)。

$ sleep 100 &
[1] 17098
$ gdb --pid=$! /bin/sleep
[...]
(gdb) p environ[0]
$1 = 0x7fffd722d227 "STY=7498.pts-0.hostname"
(gdb) p environ[1]
$2 = 0x7fffd722d245 "TERM=screen-bce"
(gdb) call system("env > /tmp/some-file")
$4 = 0
(gdb) detach
Detaching from program: /bin/sleep, process 17098
(gdb) quit
$ cat /tmp/some-file
GNOME_KEYRING_PID=6850
SSH_AGENT_PID=6844
SHLVL=1
[...]

答案2

如果您运行的是 Linux 或具有文件系统的 Unix 之一/proc,则进程的环境位于/proc.我现在无法访问 Solaris 机器,但对于 Linux 来说这是可行的:

$ tr  '\0' '\n' < /proc/$$/environ

它打印当前 shell 的环境变量,但$$可以是您的用户 ID 有权访问的任何进程 ID。

在 Solaris 下有一种方法可以做到这一点,但要复杂得多。我认为 BSD/proc与 Linux 更相似。

相关内容