我需要对与Unix系统上的环境变量有关的一些问题进行故障排除。

在Windows上,我可以使用诸如ProcessExplorer之类的工具来选择特定的进程并查看每个环境变量的值。 >
如何在Unix上完成相同的工作? echoingenv cmd目前仅显示值,但是我想查看运行进程当前正在使用的值。

评论

即使/ proc / / environ的大小为0,那里仍然有信息。 “如果将其视为进入内核的窗口,那将更有意义。该文件实际上并不包含任何数据;它只是充当指向实际过程信息所在位置的指针。” [来源]

#1 楼

cat /proc/<pid>/environ


如果要获取给定正在运行的可执行文件的pid,可以在许多其他可能性中使用pidof

AlberT$ pidof sshd   
30690 6512 


EDIT:

我完全引用Dennis Williamson和Teddy的评论来获得更具可读性的输出。
我的解决方案如下: >

评论


要使其可读,请将null转换为换行符:cat / proc / 17330 / environ | tr \\ 0 \\ n

–丹尼斯·威廉姆森
09-09-17 at 19:14

我总是做xargs --null --max-args = 1 echo
–泰迪
09-10-29在13:08

最好使用字符串,其速度很快。猫还是更快:-)

– Nikhil Mulley
2012年1月14日19:37

整个/ proc文件系统不可移植。

–丹尼尔·H
16 Dec 16'在16:49

我不明白为什么使用xargs将null转换为换行符比使用tr更好。有人可以为我布置吗?谢谢。

–乔纳森·哈特利
17年5月9日在13:55

#2 楼

由于此问题具有unix标记,并且其他所有人在解决linux标记方面都做得非常出色,因此您可以使用

ps -p <PID> -wwwe




ps -p <PID> -wwwE


以及在具有

/usr/ucb/ps -wwwe <PID>

的Solaris上,如果您不这样做,Solaris也支持/proc目录不想记住晦涩的ps命令。

评论


我在OS X 10.6上运行ps -p -wwwe,得到所有正在运行的进程的列表。正确的命令带有-E标志,而不带有-e。

–drAlberT
09年9月18日在8:17

我在OS X 10.4(而非10.5)上进行了测试。相应地更新。

–通用梳子
09-09-18 15:23

这不是完美的。 -E选项仅报告初始环境变量。如果变量已由运行中的进程本身更改(例如,通过使用POSIX putenv()函数),则更改不会反映在ps -p -wwE的输出中。

–卡尔
2013年3月1日7:11

看不到您不拥有的进程的env vars听起来像是一个不错的功能。 @drAlberT使用/ proc / PID / environ的面向Linux的答案也是如此。这些文件仅由进程的所有者读取。

–乔纳森·哈特利
17年5月9日13:58

@yani可能,但是要困难得多,它需要将调试器附加到正在运行的进程。看到这个答案:unix.stackexchange.com/a/70636

–卡尔
18年6月26日在7:54

#3 楼

就像其他人提到的那样,在Linux上,您可以查看/ proc,但是根据您的内核版本,有一个或两个限制:

首先,environ文件包含它看上去的环境当进程产生时。这意味着该进程可能对其环境所做的任何更改在/ proc中都不可见:
有限的环境,但通过采购来扩大环境,例如.bashrc,但/ proc不反映这一点。第二个shell从一开始就继承了较大的环境,这就是为什么它在/ proc中显示的原因。
此外,在较早的内核上,environ文件的内容限于页面大小(4K):

$ cat /proc/$$/environ | wc -c
320
$ bash
$ cat /proc/$$/environ | wc -c
1270
$ 


在2.6.9(RHEL4)和2.6.18(RHEL5)之间的某个位置已被删除...

评论


是否可以获取在远程进程生成后设置的环境变量?我了解在VFS上,它会显示在/ proc / self / environ中,但前提是我们在进程内部。但是如何获得一个远程进程呢?

– GP92
18年1月4日在2:36

ew!感谢您的回答,希望仍然适用。因此,启动时的环境变量对于其他用户和通过/ proc / / environ /在系统上的进程可见。无法通过/ proc /访问环境的运行时更改,但是如果它生成另一个进程,则env var最终将在其/ proc /中可见。我猜这就是为什么在使用容器时不应通过环境变量配置机密,而是通过业务流程系统或保管库api协调的机密文件来配置机密的原因。

–贾姆希德
7月4日0:55

#4 楼

正确使用BSD选项来执行此操作(至少在linux上):

ps e $pid




ps auxe  #for all processes


是的,ps联机帮助页非常令人困惑。
(通过)

评论


我的Ubuntu沿命令行粉碎了环境变量,它们之间甚至没有空格,并且在终端窗口上截断了一行。我发现ps eww $ pid解决了第二个问题。

–user18911
2013年12月3日14:42

@ user18911:env var具有空字符分隔符。本页上的其他答案显示了使用xargs或tr将其转换为换行符以提高可读性的方法。您可能在接下来的四年中意识到了这一点。

–乔纳森·哈特利
17年5月9日在14:01

#5 楼

尽管记录很少,但/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


评论


通过将这些命令以及最后的quit命令放入.gdb文件(例如〜/ penv.gdb)中,可能会更好。然后,当您要检查进程的环境时,可以通过运行gdb -x〜/ penv.gdb -p []随时使用此GDB脚本启动gdb(1)。

–低功耗
19年11月29日在4:41

#6 楼

cat /proc/PID/environ


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

示例:cat / proc / 32512 / environ

#7 楼

摘自Archlinux Wiki:

您可以创建一个临时函数来解析/proc/<pid>/environ中的值。在终端提示符下:

envof() { sed 's/\x0/\n/g' /proc//environ; }


然后使用所需进程的pid,只需使用:

envof <pid>


#8 楼

在Linux下,我尝试看看

/proc/<pid>/environ


#9 楼

对于Solaris 5.10,此方法有效:

pargs -e <PID>


#10 楼

而且由于我的工作使我成为AIX的忠实拥护者,所以请不要忘记:

ps eww [pid]


或如手册页所称的那样,它是“伯克利标准”。

由于某种原因,AIX中不存在/ proc / PID / environ。

#11 楼

如果要创建格式化的env(如用于任意进程(PID)的环境变量的输出),则可以创建一个方便的bash penv <pid>命令(针对您的OS)并将其添加到您的.bashrc中:

Linux将其添加到〜/ .bashrc:

penv () { 
    xargs --null --max-args=1 < /proc//environ
}


macOS / BSD将其添加到〜/ .bashrc:

penv() {
   ps eww -o command   | tr ' ' '\n'
}


Solaris将其添加到您的〜/ .bashrc中:

penv() {
   pargs -e 
}


用法:

$ source $HOME/.bashrc
$ pgrep VBoxSVC
10268
$ penv 10268
SSH_CONNECTION=1.1.1.242 53960 1.1.1.91 22
GREP_COLORS=sl=49;39:cx=49;39:mt=49;38;5;167;1:fn=49;39;1:ln=49;39:bn=49;39:se=50;39
LANG=en_US.UTF-8
EDITOR=vim
XDG_SESSION_ID=106
USER=root
PWD=/root
HOME=/root
SSH_CLIENT=1.1.1.242 53960 22
SSH_TTY=/dev/pts/3
MAIL=/var/mail/root
TERM=xterm-256color
SHELL=/bin/bash
SHLVL=1
LOGNAME=root
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
XDG_RUNTIME_DIR=/run/user/0
PATH=/root/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:.
VBOX_LOG_FLAGS=thread tsc
VBOX_LOG=-all+dev_vmm_backdoor.e.l.f+dev_vmm.e.l.f


#12 楼

Mac解决方案,可能还包括其他BSD,可能类似于

pid=28369; ps e $pid | cut -c$(expr 1 + $(ps p $pid|tail +2|wc -c))-


环境变量被附加到命令行,这删除了命令行,而我们只有剩下的环境变量。

这不是完美的,因为它们是空间分隔的,而不是LF分隔的

#13 楼

/ proc / PID / environ

为此,首先我们需要识别进程的PID。
为此,您可以使用ps命令