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

Como recarregar /etc/ambiente sem reiniciar?

/etc/environment é oficialmente o lugar correto para variáveis de ambiente amplo do sistema. Mas como posso reload as atribuições neste ficheiro sem reiniciar ou relogar?

Curiosamente o google não me ajuda aqui, para além das dezenas de posts de blogues que sugerem usar

source /etc/environment

que obviamente nunca funcionarão porque /etc/environment é uma lista de atribuições (uma por linha) e não um script executável (daí os comandos export em falta em /etc/environment …).

Respostas (2)

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

Uma coisa em que está enganado é que a /etc/environment requer uma reinicialização para recarregar. Isto é incorrecto. O único momento em que o ficheiro é lido é on login, quando a pilha PAM é activada - especificamente pam_env.so, que lê o ficheiro.

Fazer login e voltar a entrar aplicaria as alterações - e de facto você _ deve_ fazer isto se quiser que todos os seus processos recebam o novo ambiente. Todas as outras “soluções "2 apenas aplicarão o ambiente ao processo de shell único, mas não a nada que você lançar através da GUI incluindo novos terminais windows.1

Se não se importar com isso - a falta de comandos export pode ser compensada com set -a e set +a. No entanto, continua a ser um mau caminho, uma vez que o ficheiro também não utiliza a citação. Mas isto deve funcionar bem:

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

1 O Gestor de Sessões GNOME fornece uma forma de mudar o seu próprio ambiente, mas apenas durante a fase 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

2 gdb não é uma solução, mas pode ser usado por vezes. Tem de anexá-lo aos processos em execução do seu gestor de sessão (por exemplo, gnome-session), do seu gestor de janelas (por exemplo, gnome-shell ou openbox), da sua barra de tarefas/painel, se existir (por exemplo, xfce4-panel), e geralmente qualquer outra coisa que possa executar coisas. Para cada um desses processos, precisa de anexar o gdb por PID, invocar a função putenv() utilizando o p, e depois destacar utilizando o 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 que o depurador pausa o processo, por isso tem de anexar a composição de gestores de janelas apenas a partir de outro tty (consola virtual) ou sobre SSH, caso contrário o ecrã congelaria.

Para além disso, deve também actualizar o ambiente utilizado pelo dbus-daemon:

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

Para sistemas mais antigos:

$ 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

Isto não é tão abrangente como a resposta aceite, mas se tiver citado variáveis nos seus ficheiros /etc/environment ambos os métodos anteriores (que usam export $line de alguma forma) irão correr mal e acabará com valores cotados.

  • Opção 1: com um ficheiro temporário de origem

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

  • Opção 2: com for em linha (obrigado @tim-jones):

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