Tải lại các biến môi trường


10

Câu hỏi này đã được hỏi tại superuser là-there-a-way-to-reload-môi trường-biến-in-emacs , nhưng không có giải pháp tốt nào được đưa ra.

Tôi đang sử dụng EmacsClient với hơn 30 bộ đệm mở, nếu tôi thay đổi biến môi trường trong trình bao, tôi cần thoát EmacsClient (và mở lại tất cả các bộ đệm) hoặc tôi phải tự đặt biến môi trường trong Emacs. Tôi thấy khó chịu khi tôi không thể cập nhật các biến môi trường một cách dễ dàng trong Emacs. Bất kỳ đề xuất?


Không có cách nào đơn giản để làm điều này, bởi vì thay đổi một biến môi trường trong quy trình cha mẹ sẽ không cập nhật giá trị của nó như được xuất cho một đứa trẻ.
Erik Hetzner

Câu trả lời:


7

exec-path-from-shell cung cấp exec-path-from-shell-copy-envlệnh, cho phép bạn sao chép giá trị của các biến môi trường vào các phiên Emacs. Chẳng hạn, cũng M-x exec-path-from-shell-copy-env RET FOOđặt giá trị của $FOOEmacs.

Lưu ý rằng exec-path-from-shell-copy-envsinh ra một shell mới để trích xuất giá trị của biến môi trường. Do đó, nó sẽ chỉ hoạt động cho các biến mà bạn đặt trong các tệp cấu hình shell của mình (ví dụ .bashrc), nhưng không hoạt động cho các biến chỉ được đặt trong phiên shell đang chạy với export. Việc trích xuất các biến này nói chung là không thể nếu không có các bản hack phức tạp kiểm tra /proc/hoặc API tương tự để chạy các quy trình.


Về các giá trị sau / tạm thời, nếu Emacs đang chạy như một máy chủ thì việc chuyển các giá trị được cập nhật qua cho emacsclient trực tiếp từ shell đó sẽ đủ dễ dàng.
phils

@phils Cảm ơn, hãy xem câu trả lời cập nhật của tôi ..
Håkon Hægland

5

Như một giải pháp thay thế, những điều sau đây có thể được sử dụng (Linux, Bash):

  • Lần chạy đầu tiên printenv -0 > env.txttừ cửa sổ đầu cuối Bash,
  • Sau đó từ bên trong Emacs, chạy
(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)))))

Cập nhật

Tôi chỉ ra rằng điều này có thể được thực hiện một cách thanh lịch hơn bằng cách sử dụng --evaltùy chọn của emacsclientlệnh: Xác định tập lệnh Bash update_emacs_env:

#! /bin/bash

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

server_nametên máy chủ Emacs của bạn ở đâu và my-update-envlà một chức năng được xác định bởi ~/.emacstệp của bạn :

(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)))))

Bây giờ bạn có thể chỉ cần gõ update_emacs_envtừ dòng lệnh shell để cập nhật các biến môi trường Emacs ..


Và bạn cũng có thể chạy "printenv" từ bên trong chức năng ...
mankoff

@mankoff Thật ra, tôi nghĩ bạn không thể .. :) (Nó sẽ in các giá trị cũ rồi)
Håkon Hægland

Bạn không thể sinh ra một vỏ với cờ đăng nhập? Hoặc source.bashrc, .bash_profile, v.v.?
mankoff

Có .. nhưng nó sẽ không giúp ích gì cho trường hợp đặc biệt nếu tôi xuất trực tiếp vỏ từ dòng lệnh, sử dụngexport VAR=value
Håkon Hægland

Có, tôi đã không nghĩ về trường hợp đó. Giải pháp thanh lịch với khách hàng!
mankoff

3

Tôi đã từng sử dụng điều này:

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
}

Cho phép bạn xuất một biến được đặt tên, EG:

export EDITOR=vim
export-emacs EDITOR
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.