How to reload /etc/environment without rebooting?

163

40

/etc/environment is officially the correct place for system wide environment variables. But how can I reload the assignments in this file without rebooting or relogging?

Interestingly enough google does not help me here, aside from the dozens of blog posts suggesting to use

source /etc/environment

which obviously will never work because /etc/environment is a list of assigments (one per line) and not an executable script (hence the missing export commands in /etc/environment ...).

fgysin reinstate Monica

Posted 2011-09-25T11:27:43.623

Reputation: 2 228

2@lzkata: If a variable is already exported, it should not be necessary to export it again... If new variable that have not already been exported are added, the export would be necessary... (without it it is just a normal non-environment variable in the current shell, not available in child processes) – Gert van den Berg – 2014-09-01T10:16:04.140

@DanielBeck thank you..plz add you comment as an answer! – Gadelkareem – 2015-12-03T19:17:13.947

does it works also on debian and centos ? – Massimo – 2017-07-10T23:28:04.673

does it require user login or its settings are used also by daemons and cron jobs ? – Massimo – 2017-07-10T23:28:55.633

12Systemwide, I have no idea. For the current shell session, you can use for line in $( cat /etc/environment ) ; do export $line ; done, if the file format is key=value. – Daniel Beck – 2011-09-25T11:38:55.077

3Works for me without an export... – Izkata – 2014-03-30T14:44:57.383

Answers

126

One thing you are mistaken about is that /etc/environment requires a reboot to reload. This is incorrect. The only time the file is read is on login, when the PAM stack is activated – specifically pam_env.so, which reads the file.

Logging out and back in would apply the changes – and in fact you must do this if you want all your processes to receive the new environment. All other "solutions"2 will only apply the environment to the single shell process, but not to anything you launch through the GUI including new terminal windows.1

If you're fine with that, though – the lack of export commands can be compensated for with set -a and set +a. However, it still remains a poor way, as the file doesn't use quoting either. But this should work fine:

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

1 GNOME Session Manager provides a way to change its own environment, but only during the Initialization phase:

$ 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 is not a solution, but can be used sometimes. You have to attach it to the running processes of your session manager (e.g. gnome-session), your window manager (e.g. gnome-shell or openbox), your taskbar/panel if any (e.g. xfce4-panel), and generally anything else that possibly would run stuff. For each of those processes, you need to attach gdb to it by PID, invoke the putenv() function using p, then detach using 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

Note that the debugger pauses the process, therefore you must attach to compositing window managers only from another tty (virtual console) or over SSH, otherwise the screen would freeze.

In addition to that, you should also update the environment used by dbus-daemon:

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

For older systems:

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

user1686

Posted 2011-09-25T11:27:43.623

Reputation: 283 655

1I just tested while read -r env; do export "$env"; done on Ubuntu 16.04 and it errors. Would you like more details? – Frank – 2016-07-30T07:41:50.950

The while read method reads from stdin, so you probably want to pipe something to it (e.g. cat /etc/environment | while ...). But this won't work with quote formatted environment files (key="value") – villasv – 2017-08-14T20:06:48.950

6

This is not as comprehensive as the accepted answer, but if you have quoted variables in your /etc/environment files both previous methods (which use export $line somehow) will go wrong and you end up with quoted values.

  • Option 1: with a temporary source-able file

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

  • Option 2: with inline for (thanks @tim-jones):

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

villasv

Posted 2011-09-25T11:27:43.623

Reputation: 161

4Shorter: eval sed 's/^/export /' /etc/environment – Aaron McMillin – 2017-08-23T17:59:11.837

2Non-temp-file version of above: for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done – Tim Jones – 2018-03-16T22:27:06.273

7Even shorter: set -a; source /etc/environment; set +a;. – ulidtko – 2018-04-20T09:03:50.020