/etc/environment正式是系统范围环境变量的正确位置。但是,如何在不重新启动或重新登录的情况下重新加载此文件中的作业?

有趣的是,除了数十个建议使用

的博客帖子之外,足够多的google不能对我有帮助。
source /etc/environment


这显然是行不通的,因为/etc/environment是配置列表(每行一个),而不是可执行脚本(因此export中缺少/etc/environment命令...)。

评论

在系统范围内,我不知道。对于当前的shell会话,您可以在$(cat / etc / environment)中使用line;出口$ line;如果文件格式为key = value,则完成。

为我工作,没有出口...

@lzkata:如果已经导出了变量,则不必再次将其导出...如果添加了尚未导出的新变量,则将需要导出...(没有它只是正常现象当前外壳中的非环境变量,在子进程中不可用)

@DanielBeck谢谢..plz添加您的评论作为答案!

在debian和centos上也可以使用吗?

#1 楼

您误会的一件事是/etc/environment需要重新启动才能重新加载。这是不正确的。唯一的一次读取文件是在登录时激活了PAM堆栈-特别是pam_env.so,它读取了文件。

注销并重新登录将应用更改–实际上,您必须这样做如果您希望所有进程都接收新环境,则使用此选项。所有其他“解决方案” 2只会将环境应用于单个shell进程,而不应用于您通过GUI启动的任何程序,包括新的终端窗口。1

如果您满意的话– exportset -a可以弥补set +a命令的不足。但是,它仍然是一种糟糕的方法,因为文件也不使用引号。但这应该可以正常工作:

while read -r env; do export "$env"; done



1 GNOME会话管理器提供了一种更改其自身环境的方法,但仅限于Initialization阶段:

$ gdbus call -e -d org.gnome.SessionManager \
                -o /org/gnome/SessionManager \
                -m org.gnome.SessionManager.Setenv \
                "FOO" "bar"
Error: GDBus.Error:org.gnome.SessionManager.NotInInitialization: Setenv
    interface is only available during the Initialization phase



2 gdb不是解决方案,但有时可以使用。您必须将其附加到会话管理器(例如gnome-session),窗口管理器(例如gnome-shellopenbox),任务栏/面板(如果有)(例如xfce4-panel)以及通常可能运行的东西的运行进程中。对于每个进程,您都需要通过PID将gdb附加到其上,使用putenv()调用p函数,然后使用q分离:

$ sudo gdb -p $(pidof gnome-session)
GNU gdb (GDB) 7.7.1
[...]
Attaching to process 718
[...]
0x00007fc2cefed81d in poll () from /usr/lib/libc.so.6

(gdb) p putenv("FOO=bar")
 = 0

(gdb) p putenv("BAZ=qux")
 = 0

(gdb) q
A debugging session is active.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/gnome-session, process 718


请注意,调试器会暂停因此,您必须仅从另一个tty(虚拟控制台)或通过SSH附加到合成窗口管理器,否则屏幕将冻结。

此外,还应更新由dbus-daemon:

$ dbus-update-activation-environment --systemd FOO=bar BAZ=qux


对于旧系统:

$ gdbus call -e -d org.freedesktop.DBus \
                -o /org/freedesktop/DBus \
                -m org.freedesktop.DBus.UpdateActivationEnvironment \
                "{'FOO': 'bar', 'BAZ': 'qux'}"
()


评论


我只是在读取-r env时进行了测试;确实输出“ $ env”;在Ubuntu 16.04上完成,并报错。您想要更多细节吗?

–坦率
16年7月30日在7:41

while read方法是从stdin读取的,因此您可能希望将某些内容传递给它(例如cat / etc / environment | while ...)。但这不适用于报价格式的环境文件(key =“ value”)

–villasv
17年8月14日在20:06

谢谢!我一直在寻找(并试图提出)像您的read -r这样的优雅解决方案,以解析通用的“ env文件”,例如与Docker等一起使用的文件。这是一个更完整的示例,该示例跳过空白以#开头的行和行(今天在env文件中很常见),如果行格式错误,则退出并返回错误:while read -r pair;如果[[$ pair ==?* && $ pair!= \#*]]怎么办?然后导出“ $ pair” || 2号出口; fi;完成
– Tobia
20-3-18在11:12

#2 楼

这并不像公认的答案那样全面,但是如果您在/etc/environment文件中用引号引起来,则先前的两种方法(以某种方式使用export $line)都会出错,并且最终会用引号引起来。


选项1:带有可临时获取的源文件

sed 's/^/export /' /etc/environment > /tmp/env.sh && source /tmp/env.sh


选项2:带有内联for(感谢@ tim-jones):

for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done

评论


更简短:eval sed's / ^ / export /'/ etc / environment

–亚伦·麦克米林(Aaron McMillin)
17年8月23日在17:59



上面的非临时文件版本:用于$(en cat in cat / etc / environment);确实导出$(echo $ env | sed -e's /“ // g');完成

–蒂姆·琼斯(Tim Jones)
18 Mar 16 '18在22:27



更短:set -a;源/ etc / environment;设置+ a;。

– ulidtko
18年4月20日在9:03