¿Cómo recargar / etc / environment sin reiniciar?

157

/etc/environmentes oficialmente el lugar correcto para las variables de entorno de todo el sistema. Pero, ¿cómo puedo volver a cargar las asignaciones en este archivo sin reiniciar o volver a iniciar sesión?

Curiosamente, google no me ayuda aquí, aparte de las docenas de publicaciones de blog que sugieren usar

source /etc/environment

que obviamente nunca funcionará porque /etc/environmentes una lista de asignaciones (una por línea) y no un script ejecutable (de ahí los exportcomandos que faltan en /etc/environment...).

fgysin
fuente
11
En todo el sistema, no tengo idea. Para la sesión de shell actual, puede usar for line in $( cat /etc/environment ) ; do export $line ; done, si el formato de archivo es key=value.
Daniel Beck
2
Funciona para mí sin un export...
Izkata
2
@lzkata: Si una variable ya se exporta, no debería ser necesario volver a exportarla ... Si se agregan nuevas variables que aún no se han exportado, exportsería necesaria ... (sin ella, es simplemente un no normal -ambiente variable en el shell actual, no disponible en procesos secundarios)
Gert van den Berg
@DanielBeck gracias ... ¡por favor agrega tu comentario como respuesta!
Gadelkareem
¿Funciona también en Debian y Centos?
Massimo

Respuestas:

122

Una cosa con la que se equivoca es que /etc/environmentrequiere un reinicio para volver a cargar. Esto es incorrecto. La única vez que se lee el archivo es al iniciar sesión , cuando se activa la pila PAM, específicamente pam_env.so, que lee el archivo.

Cerrar sesión y volver a iniciarla aplicaría los cambios, y de hecho debe hacerlo si desea que todos sus procesos reciban el nuevo entorno . Todas las demás "soluciones" 2 solo aplicarán el entorno al proceso de shell único, pero no a todo lo que inicie a través de la GUI, incluidas las nuevas ventanas de terminal. 1

Sin embargo, si está de acuerdo con eso, la falta de exportcomandos se puede compensar con set -ay set +a. Sin embargo, sigue siendo un mal camino, ya que el archivo tampoco usa comillas. Pero esto debería funcionar bien:

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

1 GNOME Session Manager proporciona una forma de cambiar su propio entorno, pero 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 no es una solución, pero puede usarse a veces. Debe adjuntarlo a los procesos en ejecución de su administrador de sesión (p gnome-session. Ej. ), Su administrador de ventanas (p. Ej. gnome-shellO openbox), su barra de tareas / panel si corresponde (p xfce4-panel. Ej. ) Y, en general, cualquier otra cosa que pueda ejecutar cosas. Para cada uno de esos procesos, debe adjuntarlo gdbmediante PID, invocar la putenv()función usando p, luego desconectar usando 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

Tenga en cuenta que el depurador detiene el proceso, por lo tanto, debe adjuntar a los administradores de ventanas de composición solo desde otro tty (consola virtual) o sobre SSH; de lo contrario, la pantalla se congelaría.

Además de eso, también debe actualizar el entorno utilizado por dbus-daemon:

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

Para sistemas más antiguos:

$ gdbus call -e -d org.freedesktop.DBus \
                -o /org/freedesktop/DBus \
                -m org.freedesktop.DBus.UpdateActivationEnvironment \
                "{'FOO': 'bar', 'BAZ': 'qux'}"
()
Gravedad
fuente
1
Acabo de probar mientras leía -r env; exportar "$ env"; hecho en Ubuntu 16.04 y errores. ¿Quieres más detalles?
Frank
El while readmétodo lee stdin, por lo que probablemente desee canalizarle algo (p cat /etc/environment | while .... Ej .). Pero esto no funcionará con archivos de entorno con formato de cotización ( key="value")
villasv
6

Esto no es tan completo como la respuesta aceptada, pero si ha citado variables en sus /etc/environmentarchivos, ambos métodos anteriores (que de export $linealguna manera se usan ) saldrán mal y terminará con los valores citados.

  • Opción 1: con un archivo fuente temporal

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

  • Opción 2: con línea for(gracias @ tim-jones):

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

villasv
fuente
44
Más corto: evalsed 's/^/export /' /etc/environment
Aaron McMillin
2
Versión sin archivo temporal de la anterior:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Tim Jones
77
Aún más corto: set -a; source /etc/environment; set +a;.
ulidtko