Bagaimana cara memuat ulang / etc / environment tanpa me-reboot?

157

/etc/environmentsecara resmi tempat yang tepat untuk variabel lingkungan sistem lebar. Tetapi bagaimana saya bisa memuat ulang tugas dalam file ini tanpa me-reboot atau me-reog?

Yang cukup menarik, Google tidak membantu saya di sini, selain dari lusinan posting blog yang menyarankan untuk digunakan

source /etc/environment

yang jelas tidak akan pernah berhasil karena /etc/environmentmerupakan daftar tugas (satu per baris) dan bukan skrip yang dapat dieksekusi (karenanya exportperintah yang hilang di /etc/environment...).

fgysin
sumber
11
Di seluruh sistem, saya tidak tahu. Untuk sesi shell saat ini, Anda dapat menggunakan for line in $( cat /etc/environment ) ; do export $line ; done, jika format file adalah key=value.
Daniel Beck
2
Bekerja untukku tanpa export...
Izkata
2
@ lzkata: Jika variabel sudah diekspor, seharusnya tidak perlu mengekspor lagi ... Jika variabel baru yang belum diekspor ditambahkan, exportitu akan diperlukan ... (tanpanya itu hanya normal non variabel lingkungan dalam shell saat ini, tidak tersedia dalam proses anak)
Gert van den Berg
@DanielBeck terima kasih .. tolong tambahkan komentar Anda sebagai jawaban!
Gadelkareem
apakah itu berfungsi juga pada debian dan centos?
Massimo

Jawaban:

122

Satu hal yang salah tentang Anda adalah /etc/environmentperlu me-reboot untuk memuat ulang. Ini salah. Satu-satunya waktu file dibaca adalah saat login , ketika tumpukan PAM diaktifkan - khususnya pam_env.so, yang membaca file.

Keluar dan kembali akan menerapkan perubahan - dan pada kenyataannya Anda harus melakukan ini jika Anda ingin semua proses Anda menerima lingkungan baru . Semua "solusi" 2 lainnya hanya akan menerapkan lingkungan ke proses shell tunggal, tetapi tidak untuk apa pun yang Anda luncurkan melalui GUI termasuk jendela terminal baru. 1

Namun, jika Anda setuju dengan itu - kurangnya exportperintah dapat dikompensasi dengan set -adan set +a. Namun, ini tetap merupakan cara yang buruk, karena file tersebut tidak menggunakan penawaran. Tetapi ini seharusnya bekerja dengan baik:

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

1 Manajer Sesi GNOME menyediakan cara untuk mengubah lingkungannya sendiri, tetapi hanya selama 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 bukanlah solusi, tetapi terkadang dapat digunakan. Anda harus melampirkannya pada proses yang berjalan dari manajer sesi Anda (misalnya gnome-session), manajer jendela Anda (misalnya gnome-shellatau openbox), taskbar / panel Anda jika ada (misalnya xfce4-panel), dan umumnya hal lain yang mungkin menjalankan barang. Untuk setiap proses tersebut, Anda harus melampirkannya gdbdengan PID, menjalankan putenv()fungsi menggunakan p, lalu melepaskan menggunakan 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

Perhatikan bahwa debugger menghentikan proses, oleh karena itu Anda harus melampirkan ke compositing window manager hanya dari tty lain (konsol virtual) atau lebih dari SSH, jika tidak layar akan membeku.

Selain itu, Anda juga harus memperbarui lingkungan yang digunakan oleh dbus-daemon:

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

Untuk sistem yang lebih lama:

$ gdbus call -e -d org.freedesktop.DBus \
                -o /org/freedesktop/DBus \
                -m org.freedesktop.DBus.UpdateActivationEnvironment \
                "{'FOO': 'bar', 'BAZ': 'qux'}"
()
grawity
sumber
1
Saya baru saja menguji saat membaca -r env; lakukan ekspor "$ env"; dilakukan pada Ubuntu 16.04 dan kesalahan. Apakah Anda ingin detail lebih lanjut?
Frank
The while readmetode membaca dari stdin, sehingga Anda mungkin ingin pipa sesuatu untuk itu (misalnya cat /etc/environment | while ...). Tapi ini tidak akan berfungsi dengan file lingkungan kutipan yang diformat ( key="value")
villasv
6

Ini tidak selengkap jawaban yang diterima, tetapi jika Anda telah mengutip variabel dalam /etc/environmentfile Anda, kedua metode sebelumnya (yang menggunakan export $lineentah bagaimana) akan salah dan Anda berakhir dengan nilai yang dikutip.

  • Opsi 1: dengan file yang dapat sumber sementara

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

  • Opsi 2: dengan inline for(terima kasih @ tim-jones):

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

villasv
sumber
4
Lebih pendek: evalsed 's/^/export /' /etc/environment
Aaron McMillin
2
Versi non-temp-file di atas:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Tim Jones
7
Bahkan lebih pendek: set -a; source /etc/environment; set +a;.
ulidtko