Unix 上正在运行的进程的环境变量?

m3r*_*nEz 241 linux unix troubleshooting environment-variables process

我需要解决一些与 Unix 系统上的环境变量相关的问题。

在 Windows 上,我可以使用 ProcessExplorer 之类的工具来选择特定的进程并查看每个环境变量的值。

我怎样才能在 Unix 上完成同样的事情?echoingenvcmd 只显示当前的值,但我想查看正在运行的进程当前使用的值。

drA*_*erT 312

cat /proc/<pid>/environ
Run Code Online (Sandbox Code Playgroud)

如果您想拥有给定正在运行的可执行文件的 pid(s),您可以在许多其他可能性中使用pidof

AlberT$ pidof sshd   
30690 6512 
Run Code Online (Sandbox Code Playgroud)

编辑

我完全引用了Dennis WilliamsonTeddy 的评论以实现更具可读性的输出。我的解决方案如下:

tr '\0' '\n' < /proc/<pid>/environ
Run Code Online (Sandbox Code Playgroud)

  • 为了使其可读,将空值转换为换行符:`cat /proc/17330/environ | tr \\0 \\n` (50认同)
  • 我总是做`xargs --null --max-args=1 echo &lt; /proc/PID/environ` (34认同)
  • 更好地使用字符串,它的速度很快。猫仍然更快:-) (8认同)
  • 我不明白为什么使用 `xargs` 将空值转换为换行符比使用 `tr` 更好。有人可以帮我布置一下吗?谢谢。 (6认同)
  • 整个`/proc` 文件系统是不可移植的。 (3认同)
  • @DanielH 即使您只考虑 Linux **遵循 POSIX 和可移植性仍然是明智之举**。Linux 只是系统的内核(它提供了 `/proc` 接口),但是像 `tr`、`xargs`、`grep`、`strings` 等工具是用户空间的一部分,尽管在大多数情况下它们可以是 [GNU 工具](https://www.gnu.org/software/software.html)(这里的 `xargs` 和 `grep` 案例)它们也可以是例如 [BusyBox](https://busybox .net/),其中 GNU 扩展将不起作用。--- 所以我同意 Jonathan Hartley 的观点,没有充分的理由使用非标准的 `xargs` 代替 `tr`。 (2认同)

Ger*_*mbs 63

由于这个问题有一个unix标签,并且其他人都在解决linux标签方面做得非常出色,因此您可以在 OS X 和其他 BSD 衍生系统上使用

ps -p <PID> -wwwe
Run Code Online (Sandbox Code Playgroud)

或者

ps -p <PID> -wwwE
Run Code Online (Sandbox Code Playgroud)

和在 Solaris 上

/usr/ucb/ps -wwwe <PID>
Run Code Online (Sandbox Code Playgroud)

/proc如果您不想记住晦涩的命令,Solaris 也支持该目录ps

  • II 在 OS X 10.6 上运行 _ps -p &lt;PID&gt; -wwwe_ 我得到所有正在运行的进程的列表。正确的命令是带有 _-E_ 标志,而不是 -e。 (4认同)
  • 这并不完美。-E 选项仅报告 _initial_ 环境变量。如果正在运行的进程本身更改了变量(例如,通过使用 POSIX putenv() 函数),则更改不会反映在 `ps -p &lt;PID&gt; -wwE` 的输出中。 (4认同)

小智 26

正如其他人提到的,在 Linux 上,您可以查看 /proc,但根据您的内核版本,存在一两个限制:

首先,environ 文件包含进程生成时的环境。这意味着进程可能对其环境所做的任何更改在 /proc 中都将不可见:

$ cat /proc/$$/environ | wc -c
320
$ bash
$ cat /proc/$$/environ | wc -c
1270
$ 
Run Code Online (Sandbox Code Playgroud)

第一个 shell 是一个登录 shell,最初有一个非常有限的环境,但通过采购例如 .bashrc 来扩展它,但 /proc 没有反映这一点。第二个 shell 从一开始就继承了更大的环境,这也是它显示在 /proc 中的原因。

此外,在较旧的内核上,environ 文件的内容仅限于页面大小 (4K):

$ cat /proc/$$/environ | wc -c
4096
$ env | wc -c
10343
$ 
Run Code Online (Sandbox Code Playgroud)

在 2.6.9 (RHEL4) 和 2.6.18 (RHEL5) 之间的某个地方,这个限制被删除了......


小智 11

正确使用 BSD 选项来做到这一点(至少在 linux 上):

ps e $pid
Run Code Online (Sandbox Code Playgroud)

或者

ps auxe  #for all processes
Run Code Online (Sandbox Code Playgroud)

是的,ps 联机帮助页非常混乱。(通过)


Mic*_*ner 11

虽然文档很少,但其内容/proc/<pid>/environ将仅包含用于启动流程的环境。

如果您需要检查进程环境的当前状态,一种方法是使用gdb.

# Start gdb by attaching it to a pid or core file
gdb <executable-file> <pid or core file>

# Run the following script to dump the environment
set variable $foo = (char **) environ
set $i = 0
while ($foo[$i] != 0)
print $foo[$i++]
end
Run Code Online (Sandbox Code Playgroud)


小智 7

cat /proc/PID/environ
Run Code Online (Sandbox Code Playgroud)

用您要查看的进程的 PID 替换 PID。有关正在运行的进程的每个信息都在 /proc/PID/ 目录下

示例: cat /proc/32512/environ


小智 7

摘自Archlinux wiki

您可以创建一个临时函数来解析/proc/<pid>/environ. 在终端提示符处:

envof() { sed 's/\x0/\n/g' /proc/${1}/environ; }
Run Code Online (Sandbox Code Playgroud)

然后使用您想要的进程的pid,只需使用:

envof <pid>
Run Code Online (Sandbox Code Playgroud)


Jor*_*ril 6

在 Linux 下,我会尝试看看

/proc/<pid>/environ
Run Code Online (Sandbox Code Playgroud)


小智 6

对于 Solaris 5.10,这有效:

pargs -e <PID>
Run Code Online (Sandbox Code Playgroud)