如何获取另一个进程的环境变量?

如何获取另一个进程的环境变量?

如果我检查,我可以看到进程环境变量/proc/1/environ的空字节分隔字符串。1我想将这些变量带入我当前的环境中。是否有捷径可寻?

手册proc页给了我一个片段,它有助于逐行打印每个环境变量(cat /proc/1/environ; echo) | tr '\000' '\n'。这有助于我验证内容是否正确,但我真正需要做的是将这些变量源到我当前的 bash 会话中。

我怎么做?

答案1

以下代码将每个环境变量转换为一条export语句,并正确引用以读取到 shell 中(因为LS_COLORS例如,其中可能包含分号),然后获取它。

[不幸的是, printfin/usr/bin通常不支持%q,所以我们需要调用内置的bash。]

. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)

答案2

bash可以执行以下操作。这适用于变量的所有可能内容并避免eval

while IFS= read -rd '' var; do declare +x "$var"; done </proc/$PID/environ

这会将读取的变量声明为正在运行的 shell 中的 shell 变量。要将变量导出到正在运行的 shell 环境中:

while IFS= read -rd '' var; do export "$var"; done </proc/$PID/environ

答案3

在这个答案中,我假设一个系统/proc/$pid/environ返回具有指定 PID 的进程环境,变量定义之间带有空字节。 (Linux、Cygwin 或 Solaris(?))。

兹什

export "${(@ps:\000:)$(</proc/$pid/environ)}"

(非常简单,就像 zsh 所说的那样:没有命令的输入重定向 <FILE相当于cat FILE.命令替换的输出经过参数扩展旗帜 ps:\000:意思是“分割空字节”,@意思是“如果整个内容都在双引号中,则将每个数组元素视为一个单独的字段”(概括"$@")。)

重击、mksh

while IFS= read -r -d "" PWD; do export "$PWD"; done </proc/$pid/environ
PWD=$(pwd)

(在这些 shell 中,传递的空分隔符会read导致空字节成为分隔符。我将其用作PWD临时变量名称,以避免破坏可能最终导入的另一个变量。虽然从技术上讲您PWD也可以导入,但它只会保持不变,直到下一个cd。)

POSIX

POSIX 可移植性对于这个问题来说并不是那么有趣,因为它仅适用于具有/proc/PID/environ.所以问题是 Solaris sed 支持什么——或者 Solaris 是否支持/proc/PID/environ,它过去没有支持,但我在 Solaris 功能方面远远落后于曲线,所以现在可能会支持。在 Linux 上,GNU 实用程序和 BusyBox 都是空安全的,但有一些警告。

如果我们确实坚持 POSIX 可移植性,则不需要任何 POSIX 文本实用程序来处理空字节,因此这很困难。这是一个假设 awk 支持空字节作为记录分隔符的解决方案(nawk 和 gawk 支持,BusyBox awk 也支持,但 mawk 不支持)。

eval $(</proc/$pid/environ awk -v RS='\0' '{gsub("\047", "\047\\\047\047"); print "export \047" $0 "\047"}')

BusyBox awk(嵌入式 Linux 系统上常见的版本)确实支持空字节,但不支持在块中设置RSto ,也不支持上面的命令行语法;但它确实支持.我还没有调查为什么,这看起来像是我的版本(Debian wheezy)中的一个错误。"\0"BEGIN-v 'RS="\0"'

(在转义值内的单引号后,将所有以空分隔的记录括在单引号中。 )"\047"

注意事项

请注意,其中任何一个都可能尝试设置只读变量(如果您的 shell 有只读变量)。

答案4

使用source流程替代:

source <(sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ)

不久:

. <(sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ)

使用eval命令替换:

eval `sed -r -e 's/([^\x00]*)\x00/export \1\n/g' /proc/1/environ`

sed调用可以替换为以下awk调用:

awk -vRS='\x00' '{ print "export", $0 }' /proc/1/environ

但不要忘记,它不会清除 pid 1 之外的任何环境变量。

相关内容