Как перезагрузить / etc / environment без перезагрузки?

157

/etc/environmentэто официально правильное место для общесистемных переменных среды. Но как я могу перезагрузить назначения в этом файле без перезагрузки или повторного входа?

Интересно, что Google не помогает мне здесь, кроме десятков сообщений в блогах, предлагающих использовать

source /etc/environment

что, очевидно, никогда не сработает, потому что /etc/environmentэто список назначений (по одному на строку), а не исполняемый скрипт (отсюда и отсутствующие exportкоманды в /etc/environment...).

fgysin
источник
11
По всей системе понятия не имею. Для текущего сеанса оболочки вы можете использовать for line in $( cat /etc/environment ) ; do export $line ; done, если формат файла key=value.
Даниэль Бек
2
У меня работает без export...
Izkata
2
@lzkata: Если переменная уже экспортирована, нет необходимости ее снова экспортировать ... Если добавится новая переменная, которая еще не была экспортирована, это exportбудет необходимо ... (без нее это просто обычный переменная окружения в текущей оболочке, недоступна в дочерних процессах)
Герт ван ден Берг
@DanielBeck спасибо .. пожалуйста добавьте свой комментарий в качестве ответа!
Гаделкарем
это работает также на Debian и Centos?
Массимо

Ответы:

122

Одна вещь, в которой вы ошибаетесь, это то, что /etc/environmentдля перезагрузки требуется перезагрузка. Это неверно Единственный раз, когда файл читается, это при входе в систему , когда активируется стек PAM, в частности pam_env.so, который читает файл.

Выход из системы и повторный вход будут применять изменения - и на самом деле вы должны сделать это, если хотите, чтобы все ваши процессы получили новую среду . Все остальные «решения» 2 будут применять среду только к одному процессу оболочки, но не ко всему, что вы запускаете через графический интерфейс, включая новые окна терминала. 1

Однако, если вы согласны с этим - отсутствие exportкоманд можно компенсировать с помощью set -aи set +a. Тем не менее, это все еще плохой способ, поскольку файл также не использует кавычки. Но это должно работать нормально:

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

1 GNOME Session Manager предоставляет способ изменить свою собственную среду, но только на 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 не является решением, но иногда может использоваться. Вы должны прикрепить его к запущенным процессам вашего менеджера сеансов (например gnome-session), вашего оконного менеджера (например, gnome-shellили openbox), панели задач / панели, если таковые имеются (например xfce4-panel), и вообще ко всему, что, возможно, могло бы запустить вещи. Для каждого из этих процессов вам нужно присоединиться gdbк нему с помощью PID, вызвать putenv()функцию с помощью p, а затем отключить с помощью 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

Обратите внимание, что отладчик приостанавливает процесс, поэтому вы должны подключаться к оконным менеджерам композитинга только из другого tty (виртуальной консоли) или через SSH, иначе экран зависнет.

В дополнение к этому, вы также должны обновить среду, используемую dbus-daemon:

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

Для старых систем:

$ gdbus call -e -d org.freedesktop.DBus \
                -o /org/freedesktop/DBus \
                -m org.freedesktop.DBus.UpdateActivationEnvironment \
                "{'FOO': 'bar', 'BAZ': 'qux'}"
()
grawity
источник
1
Я только что проверил, пока читаю -r env; сделать экспорт "$ env"; сделано на Ubuntu 16.04 и в нем ошибки. Хотите узнать больше?
Фрэнк
while readМетод читает stdin, так что вы , вероятно , хотите что - то трубы к нему (например cat /etc/environment | while ...). Но это не будет работать с файлами среды, отформатированными в key="value"
кавычках
6

Это не так исчерпывающе, как принятый ответ, но если вы указали переменные в своих /etc/environmentфайлах в кавычках, оба предыдущих метода (которые export $lineкаким-либо образом используют ) пойдут не так, и вы получите кавычки.

  • Вариант 1: с временным исходным файлом

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

  • Вариант 2: со встроенным for(спасибо @ Тим-Джонс):

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

villasv
источник
4
Короче: Эвалsed 's/^/export /' /etc/environment
Аарон Макмиллин
2
Не временная версия файла выше:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Тим Джонс
7
Еще короче set -a; source /etc/environment; set +a;.
ulidtko