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

fgy*_*sin 192 environment-variables ubuntu

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

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

source /etc/environment
Run Code Online (Sandbox Code Playgroud)

这显然永远不会工作,因为它/etc/environment是一个赋值列表(每行一个)而不是一个可执行脚本(因此缺少...中的export命令/etc/environment)。

use*_*686 139

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

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

但是,如果您对此感到满意 -export可以使用set -a和来弥补命令的缺失set +a。但是,它仍然是一种糟糕的方式,因为该文件也不使用引用。但这应该可以正常工作:

while read -r env; do export "$env"; done
Run Code Online (Sandbox Code Playgroud)

1 GNOME Session Manager 提供了一种改变自身环境的方法,但仅限于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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

除此之外,您还应该更新 dbus-daemon 使用的环境:

$ dbus-update-activation-environment --systemd FOO=bar BAZ=qux
Run Code Online (Sandbox Code Playgroud)

对于旧系统:

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


vil*_*asv 8

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

  • 更短:`set -a; 源 /etc/environment; 设置 +a;`。 (11认同)
  • 更短: eval `sed 's/^/export /' /etc/environment` (4认同)
  • 以上的非临时文件版本:`for env in $( cat /etc/environment ); 做出口 $(echo $env | sed -e 's/"//g'); done` (2认同)