答案1
环境是沿着系统调用传递的字符串列表execve
,就像参数列表一样。时期。应用程序如何处理它收到的字符串列表取决于应用程序。
现在,按照惯例,该列表的使用方式通常与参数列表不同。程序通常会记住它们接收到的环境变量列表,并在执行另一个命令时重复使用相同的环境变量。
他们有 C 库函数来帮助他们做到这一点:环境作为变量提供,您可以使用、、 和 等函数检索environ
和修改该列表(它收到的环境变量列表的副本)getenv
,, , ...在执行命令时使用该变量(使用他们正在跟踪的变量进行调用)。setenv
putenv
execvp
execl
system
popen
environ
execve
environ
现在应用程序不必使用该 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 更相似。