Як перезавантажити / etc / environment без перезавантаження?


157

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

Цікаво, що Google не допомагає мені тут, окрім десятків публікацій у блозі, які пропонують використовувати

source /etc/environment

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


11
В усьому світі я поняття не маю. Для поточного сеансу оболонки ви можете використовувати for line in $( cat /etc/environment ) ; do export $line ; done, якщо формат файлу є key=value.
Даніель Бек

2
Працює для мене без export...
Ізката

2
@lzkata: Якщо змінна вже експортується, її не потрібно буде знову експортувати ... Якщо нова змінна, яка вже не була експортована, буде додана, то exportце буде потрібно ... (без неї це просто нормальна -змінна середовище в поточній оболонці, недоступна в дочірніх процесах)
Герт ван ден Берг

@DanielBeck дякую..plz додати коментар як відповідь!
Gadelkareem

це працює також на debian і centos?
Массімо

Відповіді:


122

Ви помиляєтесь з тим, що /etc/environmentдля перезавантаження потрібна перезавантаження. Це неправильно. Єдиний раз, коли файл читається, це вхід у систему , коли активований стек PAM - зокрема pam_env.so, який читає файл.

Вихід із системи та їх повторне використання застосують ці зміни - і ви дійсно повинні зробити це, якщо ви хочете, щоб усі ваші процеси отримували нове середовище . Усі інші "рішення" 2 застосовуватимуть середовище лише до процесу однієї оболонки, але не до всього, що ви запускаєте через GUI, включаючи нові вікна терміналу. 1

Якщо ви все добре з цим - відсутність exportкоманд можна компенсувати за допомогою set -aта і set +a. Однак це все ще залишається поганим способом, оскільки файл також не використовує цитування. Але це повинно працювати добре:

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

1 Менеджер сесій GNOME пропонує спосіб змінити власне середовище, але лише під час 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'}"
()

1
Я просто перевіряв, читаючи -r env; зробити експорт "$ env"; зроблено на Ubuntu 16.04, і це помилки. Хочете більше деталей?
Френк

while readМетод читає stdin, так що ви , ймовірно , хочете що - то труби до нього (наприклад cat /etc/environment | while ...). Але це не працюватиме з форматованими файлами оточення ( key="value")
villasv

6

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

  • Варіант 1: з тимчасовим файлом, який може працювати з джерелом

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

  • Варіант 2: вбудований for(спасибі @ tim-jones):

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


4
Коротше: evalsed '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;.
улідко
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.