Como recarregar / etc / environment sem reiniciar?

157

/etc/environmenté oficialmente o local correto para variáveis ​​de ambiente em todo o sistema. Mas como posso recarregar as atribuições neste arquivo sem reiniciar ou registrar novamente?

Curiosamente, o Google não me ajuda aqui, além das dezenas de postagens do blog que sugerem usar

source /etc/environment

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

fgysin
fonte
11
Em todo o sistema, não faço ideia. Para a sessão de shell atual, você pode usar for line in $( cat /etc/environment ) ; do export $line ; done, se o formato do arquivo é key=value.
Daniel Beck
2
Funciona para mim sem um export...
Izkata
2
@lzkata: Se uma variável já foi exportada, não será necessário exportá-la novamente ... Se uma nova variável que ainda não foi exportada for adicionada, exportisso seria necessário ... (sem ela, é apenas uma variável normal não variável -Ambiente no shell atual, não disponível em processos filhos)
Gert van den Berg
@DanielBeck thank you..plz adiciona seu comentário como resposta!
Gadelkareem 3/15/15
funciona também no debian e centos?
Massimo

Respostas:

122

Uma coisa que você está enganado é que /etc/environmentrequer uma reinicialização para recarregar. Isto está incorreto. A única vez que o arquivo é lido é no logon , quando a pilha PAM é ativada - especificamente pam_env.so, que lê o arquivo.

Sair e voltar a aplicar as alterações - e, de fato, você deve fazer isso se desejar que todos os seus processos recebam o novo ambiente . Todas as outras "soluções" 2 aplicarão o ambiente apenas ao processo de shell único, mas não a qualquer coisa iniciada por meio da GUI, incluindo novas janelas de terminal. 1

Se você está bem com isso, porém - a falta de exportcomandos pode ser compensada com set -ae set +a. No entanto, ainda permanece um caminho ruim, pois o arquivo também não usa aspas. Mas isso deve funcionar bem:

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

1 O GNOME Session Manager fornece uma maneira de mudar seu próprio ambiente, mas apenas durante a 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 não é uma solução, mas pode ser usado algumas vezes. Você precisa anexá-lo aos processos em execução do seu gerenciador de sessões (por exemplo gnome-session), seu gerenciador de janelas (por exemplo gnome-shellou openbox), sua barra de tarefas / painel, se houver (por exemplo xfce4-panel) e, geralmente, qualquer outra coisa que possa executar coisas. Para cada um desses processos, você precisa anexar gdba ele pelo PID, chamar a putenv()função usando e p, em seguida, 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

Observe que o depurador interrompe o processo; portanto, você deve se conectar aos gerenciadores de janelas de composição apenas de outro tty (console virtual) ou sobre SSH; caso contrário, a tela congelaria.

Além disso, você também deve atualizar o ambiente usado 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'}"
()
gravidade
fonte
11
Acabei de testar enquanto lia -r env; exporte "$ env"; feito no Ubuntu 16.04 e erros. Deseja mais detalhes?
30716 Frank
O while readmétodo lê stdin, então você provavelmente deseja canalizar algo para ele (por exemplo cat /etc/environment | while ...). Mas isso não vai trabalhar com arquivos ambiente quote formatado ( key="value")
villasv
6

Isso não é tão abrangente quanto a resposta aceita, mas se você citou variáveis ​​em seus /etc/environmentarquivos, os dois métodos anteriores (que de export $linealguma forma usam ) darão errado e você terá valores citados.

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

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

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

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

villasv
fonte
4
Shorter: eval #sed 's/^/export /' /etc/environment
Aaron McMillin
2
Versão fora do arquivo temporário acima:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Tim Jones
7
Ainda mais curto: set -a; source /etc/environment; set +a;.
ulidtko