如何在不重新启动的情况下重新加载/ etc / environment?


157

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

有趣的是,除了数十篇建议使用的博客文章外,谷歌对我没有帮助

source /etc/environment

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


11
在系统范围内,我不知道。对于当前的Shell会话,for line in $( cat /etc/environment ) ; do export $line ; done如果文件格式为,则可以使用key=value
丹尼尔·贝克

2
在没有export...的情况下为我工作...
Izkata 2014年

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

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

它对debian和centos也有效吗?
马西莫

Answers:


122

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

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

不过,如果您对此感到满意,export可以使用set -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)以及通常可能运行内容的任何其他东西的运行进程中。对于每个进程,您都需要gdb通过PID 对其进行附加,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")
$1 = 0

(gdb) p putenv("BAZ=qux")
$2 = 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'}"
()

1
我只是在读-r env时测试过;确实输出“ $ env”;在Ubuntu 16.04上完成,它出错。您想要更多细节吗?
弗兰克,

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

6

这并不像公认的答案那么全面,但是如果您在/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


4
简短说明:评估sed 's/^/export /' /etc/environment
亚伦·麦克米林

2
上面的非临时文件版本:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
蒂姆·琼斯

7
甚至更短:set -a; source /etc/environment; set +a;
ulidtko '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.