โหลดตัวแปรสภาวะแวดล้อมอีกครั้ง


10

คำถามนี้ถูกถามที่ superuser มีวิธีโหลดตัวแปรสภาพแวดล้อมใน emacsแต่ไม่มีวิธีแก้ปัญหาที่ดีเลย

ฉันใช้ EmacsClient ที่เปิดบัฟเฟอร์มากกว่า 30 ครั้งหากฉันเปลี่ยนตัวแปรสภาพแวดล้อมในเชลล์ฉันต้องออกจาก EmacsClient (และเปิดบัฟเฟอร์ทั้งหมดอีกครั้ง) หรือฉันต้องตั้งค่าตัวแปรสภาพแวดล้อมด้วยตนเองใน Emacs ด้วยตนเอง ฉันพบว่ามันน่ารำคาญที่ฉันไม่สามารถอัพเดตตัวแปรสภาพแวดล้อมได้อย่างง่ายดายใน Emacs ข้อเสนอแนะใด ๆ


ไม่มีวิธีที่ตรงไปตรงมาในการทำเช่นนี้เพราะการเปลี่ยนแปลงตัวแปรสภาพแวดล้อมในกระบวนการหลักจะไม่ปรับปรุงค่าของมันเมื่อส่งออกไปยังเด็ก
Erik Hetzner

คำตอบ:


7

exec-path-from-shellจัดเตรียมexec-path-from-shell-copy-envคำสั่งซึ่งให้คุณคัดลอกค่าของตัวแปรสภาวะแวดล้อมไปยังเซสชัน Emacs ตัวอย่างเช่นM-x exec-path-from-shell-copy-env RET FOOตั้งค่า$FOOเป็น Emacs เช่นกัน

โปรดทราบว่าexec-path-from-shell-copy-envวางไข่เชลล์ใหม่เพื่อแยกค่าของตัวแปรสภาพแวดล้อม ดังนั้นมันจะทำงานเฉพาะกับตัวแปรที่คุณตั้งค่าในไฟล์การกำหนดค่าเชลล์ (เช่น.bashrc) แต่ไม่ใช่สำหรับตัวแปรที่ตั้งค่าไว้ในเซสชั่นเชลล์ที่กำลังทำงานexportเท่านั้น โดยทั่วไปการแยกตัวแปรเหล่านี้เป็นไปไม่ได้โดยไม่มีแฮ็กที่ซับซ้อนที่ตรวจสอบ/proc/หรือ API ที่คล้ายกันสำหรับกระบวนการทำงาน


เกี่ยวกับค่าหลัง / transient ถ้า Emacs ทำงานเป็นเซิร์ฟเวอร์แล้วส่งค่าที่อัปเดตไปยัง emacsclient โดยตรงจากเชลล์นั้นจะง่ายพอ
phils

@phils ขอบคุณดูคำตอบที่อัปเดตแล้วของฉัน ..
HåkonHægland

5

สามารถใช้งานต่อไปนี้ (Linux, Bash):

  • รันครั้งแรกprintenv -0 > env.txtจากหน้าต่างเทอร์มินัล Bash
  • จากนั้นจากภายใน Emacs ให้เรียกใช้
(defun my-update-env ()
  (interactive)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents "env.txt")
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

ปรับปรุง

ฉันกลับกลายเป็นว่าสิ่งนี้สามารถทำได้อย่างหรูหรามากขึ้นโดยใช้--evalตัวเลือกของemacsclientคำสั่ง: กำหนดสคริปต์ Bash update_emacs_env:

#! /bin/bash

fn=tempfile
printenv -0 > "$fn" 
emacsclient -s server_name -e '(my-update-env "'"$fn"'")' >/dev/null

server_nameชื่อเซิร์ฟเวอร์ Emacs ของคุณอยู่ที่ไหนและmy-update-envเป็นฟังก์ชั่นที่กำหนดโดย~/.emacsไฟล์ของคุณ:

(defun my-update-env (fn)
  (let ((str 
         (with-temp-buffer
           (insert-file-contents fn)
           (buffer-string))) lst)
    (setq lst (split-string str "\000"))
    (while lst
      (setq cur (car lst))
      (when (string-match "^\\(.*?\\)=\\(.*\\)" cur)
        (setq var (match-string 1 cur))
        (setq value (match-string 2 cur))
        (setenv var value))
      (setq lst (cdr lst)))))

ตอนนี้คุณสามารถพิมพ์update_emacs_envจากบรรทัดคำสั่ง shell เพื่ออัพเดทตัวแปรสภาพแวดล้อม Emacs


และคุณสามารถเรียกใช้ "printenv" จากภายในฟังก์ชันเกินไป ...
Mankoff

@mankoff ที่จริงฉันคิดว่าคุณไม่สามารถ .. :) (มันจะพิมพ์ค่าเก่าแล้ว)
HåkonHægland

คุณไม่สามารถวางไข่เชลล์ด้วยการตั้งค่าสถานะล็อกอินได้หรือไม่? หรือ. sourcebashrc, .bash_profile ฯลฯ
mankoff

ใช่ .. แต่มันจะไม่ช่วยในกรณีพิเศษถ้าฉันส่งออกในเปลือกโดยตรงจากบรรทัดคำสั่งโดยใช้export VAR=value
HåkonHægland

ใช่ฉันไม่ได้คิดถึงกรณีนั้น ทางออกที่สง่างามกับลูกค้า!
mankoff

3

ฉันเคยใช้สิ่งนี้:

function export-emacs {
    if [ "$(emacsclient -e t)" != 't' ]; then
        return 1
    fi

    for name in "${@}"; do
        value=$(eval echo \"\$${name}\")
        emacsclient -e "(setenv \"${name}\" \"${value}\")" >/dev/null
    done
}

ให้คุณส่งออกตัวแปรที่ตั้งชื่อ EG:

export EDITOR=vim
export-emacs EDITOR
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.