Come ricaricare / etc / environment senza riavviare?


157

/etc/environmentè ufficialmente il posto giusto per le variabili di ambiente a livello di sistema. Ma come posso ricaricare le assegnazioni in questo file senza riavviare o registrare di nuovo?

È interessante notare che Google non mi aiuta qui, a parte le dozzine di post sul blog che suggeriscono di utilizzare

source /etc/environment

che ovviamente non funzionerà mai perché /etc/environmentè un elenco di assegnazioni (uno per riga) e non uno script eseguibile (da qui i exportcomandi mancanti in /etc/environment...).


11
A livello di sistema, non ne ho idea. Per la sessione di shell corrente, è possibile utilizzare for line in $( cat /etc/environment ) ; do export $line ; done, se il formato del file è key=value.
Daniel Beck

2
Funziona per me senza export...
Izkata,

2
@lzkata: se una variabile è già stata esportata, non dovrebbe essere necessario esportarla di nuovo ... Se si aggiungono nuove variabili che non sono già state esportate, exportsarebbe necessario ... (senza di essa è solo un normale non -ambiente variabile nella shell corrente, non disponibile nei processi figlio)
Gert van den Berg

@DanielBeck grazie..plz aggiungi il tuo commento come risposta!
Gadelkareem,

funziona anche su debian e centos?
Massimo

Risposte:


122

Una cosa di cui ti sbagli è che /etc/environmentrichiede un riavvio per ricaricare. Questo non è corretto L'unica volta che il file viene letto è al momento dell'accesso , quando lo stack PAM è attivato, in particolare pam_env.so, che legge il file.

Disconnettersi e riconnettersi applicherebbe le modifiche e, in effetti, è necessario farlo se si desidera che tutti i processi ricevano il nuovo ambiente . Tutte le altre "soluzioni" 2 applicheranno l'ambiente solo al processo della singola shell, ma non a tutto ciò che viene avviato tramite la GUI, comprese le nuove finestre del terminale. 1

Se stai bene con quello, però - la mancanza di exportcomandi può essere compensata con set -ae set +a. Tuttavia, rimane ancora un modo scadente, in quanto il file non usa neanche il preventivo. Ma questo dovrebbe funzionare bene:

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

1 GNOME Session Manager fornisce un modo per cambiare il proprio ambiente, ma solo durante la Initializationfase:

$ 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 non è una soluzione, ma a volte può essere utilizzato. Devi collegarlo ai processi in esecuzione del gestore della sessione (ad es. gnome-session), Del gestore della finestra (ad es. gnome-shellO openbox), della barra delle attività / del pannello se presente (ad es. xfce4-panel) E in generale di qualsiasi altra cosa che possa eseguire roba. Per ciascuno di questi processi, è necessario collegarsi gdbtramite PID, richiamare la putenv()funzione utilizzando p, quindi staccare utilizzando 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

Si noti che il debugger mette in pausa il processo, quindi è necessario collegarsi ai gestori di finestre di composizione solo da un'altra tty (console virtuale) o su SSH, altrimenti lo schermo si bloccherebbe.

Inoltre, è necessario aggiornare anche l'ambiente utilizzato da dbus-daemon:

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

Per i sistemi più vecchi:

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

1
Ho appena provato mentre leggevo -r env; esportare "$ env"; fatto su Ubuntu 16.04 ed errori. Vuoi maggiori dettagli?
Frank,

Il while readmetodo legge stdin, quindi probabilmente vorrai dirottare qualcosa (ad es cat /etc/environment | while ....). Ma questo non funzionerà con i file di ambiente in formato preventivo ( key="value")
villasv

6

Questo non è completo come la risposta accettata, ma se hai citato le variabili nei tuoi /etc/environmentfile entrambi i metodi precedenti (che usano in export $linequalche modo) andranno male e finirai con i valori tra virgolette.

  • Opzione 1: con un file temporaneo abilitato all'origine

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

  • Opzione 2: con inline for(grazie @ tim-jones):

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


4
Più breve: evalsed 's/^/export /' /etc/environment
Aaron McMillin il

2
Versione non temporanea di cui sopra:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Tim Jones

7
Ancora più breve: set -a; source /etc/environment; set +a;.
Ulidtko,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.