จะรีโหลด / etc / environment โดยไม่ทำการบูทใหม่ได้อย่างไร?


157

/etc/environmentเป็นตำแหน่งที่ถูกต้องอย่างเป็นทางการสำหรับตัวแปรสภาพแวดล้อมทั้งระบบ แต่ฉันจะโหลดการมอบหมายใหม่ในไฟล์นี้โดยไม่ต้องรีบู๊ตหรือรีโหลดใหม่ได้อย่างไร

น่าสนใจพอที่ google ไม่ช่วยฉันที่นี่นอกเหนือจากโพสต์บล็อกที่แนะนำให้ใช้

source /etc/environment

ซึ่งเห็นได้ชัดว่าจะไม่ทำงานเพราะ/etc/environmentเป็นรายการของ assigments (หนึ่งต่อบรรทัด) และไม่ใช่สคริปต์ที่ปฏิบัติการได้ (ดังนั้นexportคำสั่งที่ขาดหายไปใน/etc/environment... )


11
ทั้งระบบฉันไม่มีความคิด สำหรับเซสชันเปลือกปัจจุบันคุณสามารถใช้ถ้ารูปแบบไฟล์เป็นfor line in $( cat /etc/environment ) ; do export $line ; done key=value
Daniel Beck

2
ทำงานให้ฉันได้โดยไม่ต้องมีexport...
Izkata

2
@lzkata: หากตัวแปรถูกส่งออกไปแล้วมันไม่จำเป็นที่จะต้องทำการส่งออกอีกครั้ง ... หากมีการเพิ่มตัวแปรใหม่ที่ยังไม่ได้ถูกส่งออกตัวแปรที่exportจำเป็นจะต้อง ... - ตัวแปรสภาพแวดล้อมในเชลล์ปัจจุบันไม่สามารถใช้ได้ในกระบวนการลูก)
Gert van den Berg

@DanielBeck ขอบคุณ .. กรุณาเพิ่มความคิดเห็นเป็นคำตอบ!
Gadelkareem

มันใช้งานได้กับเดเบียนและเซ็นโตสด้วย?
Massimo

คำตอบ:


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) และโดยทั่วไปสิ่งอื่นใดที่อาจเรียกใช้เนื้อหา สำหรับแต่ละกระบวนการคุณต้องแนบgdbPID เรียกใช้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
Shorter: evalsed 's/^/export /' /etc/environment
Aaron McMillin

2
เวอร์ชันที่ไม่ใช่ไฟล์ชั่วคราวด้านบน:for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done
Tim Jones

7
set -a; source /etc/environment; set +a;แม้สั้น:
ulidtko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.