2011-09-25 11:27:43 +0000 2011-09-25 11:27:43 +0000
163
163

Wie kann /etc/environment ohne Neustart neu geladen werden?

/etc/environment ist offiziell der richtige Ort für systemweite Umgebungsvariablen. Aber wie kann ich die Zuweisungen in dieser Datei neuladen, ohne neu zu booten oder neu zu loggen?

Interessanterweise hilft mir Google hier nicht weiter, abgesehen von den Dutzenden von Blog-Einträgen, die vorschlagen,

source /etc/environment

zu benutzen, was offensichtlich niemals funktionieren wird, weil /etc/environment eine Liste von Zuweisungen (eine pro Zeile) ist und nicht ein ausführbares Skript (daher die fehlenden export-Befehle in /etc/environment …).

Antworten (2)

126
126
126
2011-09-25 14:52:06 +0000

Eine Sache, in der Sie sich irren, ist, dass /etc/environment einen Neustart erfordert, um neu zu laden. Dies ist falsch. Das einzige Mal, daß die Datei gelesen wird, ist bei der Anmeldung, wenn der PAM-Stack aktiviert wird - konkret pam_env.so, der die Datei liest.

Ausloggen und wieder einloggen würde die Änderungen übernehmen - und tatsächlich muß man das tun, wenn man will, daß alle Prozesse die neue Umgebung erhalten. Alle anderen “Lösungen "2 werden die Umgebung nur auf den Single-Shell-Prozeß anwenden, aber nicht auf alles, was Sie über die GUI starten, einschließlich neuer Terminalfenster.1

Wenn Sie damit einverstanden sind - das Fehlen von export-Befehlen kann jedoch mit set -a und set +a kompensiert werden. Es bleibt jedoch immer noch ein schlechter Weg, da die Datei auch keine Anführungszeichen verwendet. Aber das sollte gut funktionieren:

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

1 GNOME-Sitzungs-Manager bietet eine Möglichkeit, seine eigene Umgebung zu ändern, aber nur während der 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 ist keine Lösung, kann aber manchmal verwendet werden. Sie müssen es an die laufenden Prozesse Ihres Sitzungsmanagers (z.B. gnome-session), Ihres Windowmanagers (z.B. gnome-shell oder openbox), Ihrer Taskleiste/Panel, falls vorhanden (z.B. xfce4-panel), und generell an alles andere, was möglicherweise Dinge ausführen würde, anhängen. Für jeden dieser Prozesse müssen Sie gdb per PID an ihn anhängen, die Funktion putenv() mit p aufrufen und dann mit q trennen:

$ 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

Beachten Sie, dass der Debugger den Prozess pausiert, daher dürfen Sie an Compositing-Fenster-Manager nur von einem anderen tty (virtuelle Konsole) oder über SSH anhängen, sonst würde der Bildschirm einfrieren.

Zusätzlich dazu, sollten Sie auch die von dbus-daemon verwendete Umgebung aktualisieren:

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

Für ältere Systeme:

$ gdbus call -e -d org.freedesktop.DBus \
                -o /org/freedesktop/DBus \
                -m org.freedesktop.DBus.UpdateActivationEnvironment \
                "{'FOO': 'bar', 'BAZ': 'qux'}"
()
6
6
6
2017-08-14 20:12:59 +0000

Dies ist nicht so umfassend wie die akzeptierte Antwort, aber wenn Sie Variablen in Ihren /etc/environment-Dateien in Anführungszeichen gesetzt haben, gehen beide vorherigen Methoden (die irgendwie export $line verwenden) schief und Sie erhalten am Ende zitierte Werte.

  • Option 1: mit einer temporären quellfähigen Datei

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

  • Option 2: mit Inline for (danke @tim-jones):

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