Załaduj ponownie zmienne środowiskowe

10

To pytanie zostało zadane na stronie superużytkownika, że istnieje sposób na przeładowanie zmiennych środowiskowych w emacach , ale nie podano dobrego rozwiązania.

Używam EmacsClient z często więcej niż 30 otwartymi buforami, jeśli zmienię zmienną środowiskową w powłoce, muszę wyjść z EmacsClient (i ponownie otworzyć wszystkie bufory) lub muszę ręcznie ustawić zmienną środowiskową również w Emacsie. Uważam za denerwujące, że nie mogę łatwo zaktualizować zmiennych środowiskowych w Emacsie. Jakieś sugestie?

Håkon Hægland
źródło
Nie ma prostego sposobu, aby to zrobić, ponieważ zmiana zmiennej środowiskowej w procesie nadrzędnym nie zaktualizuje jej wartości po wyeksportowaniu do dziecka.
Erik Hetzner,

Odpowiedzi:

7

exec-path-from-shell udostępnia exec-path-from-shell-copy-envpolecenie, które pozwala skopiować wartość zmiennych środowiskowych do sesji Emacsa. Na przykład M-x exec-path-from-shell-copy-env RET FOOustawia także wartość $FOOw Emacsie.

Zauważ, że exec-path-from-shell-copy-envspawnuje nową powłokę, aby wyodrębnić wartość zmiennej środowiskowej. Dlatego będzie działał tylko dla zmiennych, które ustawisz w plikach konfiguracyjnych powłoki (np. .bashrc), Ale nie będzie działał tylko dla zmiennych ustawianych w uruchomionej sesji powłoki z export. Wyodrębnienie tych zmiennych jest zasadniczo niemożliwe bez zawiłych włamań, które sprawdzają /proc/lub podobne API pod kątem uruchomionych procesów.

księżycowy
źródło
Jeśli chodzi o te ostatnie / przejściowe wartości, jeśli Emacs działa jako serwer, przekazywanie zaktualizowanych wartości do emacsclient bezpośrednio z tej powłoki byłoby dość łatwe.
phils
@phils Dzięki, zobacz moją zaktualizowaną odpowiedź ..
Håkon Hægland
5

Jako obejście można zastosować następujące (Linux, Bash):

  • Najpierw uruchom printenv -0 > env.txtz okna terminala Bash,
  • Następnie z poziomu Emacsa uruchom
(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)))))

Aktualizacja

Okazuje się, że można to zrobić bardziej elegancko, używając --evalopcji emacsclientpolecenia: Zdefiniuj skrypt Bash update_emacs_env:

#! /bin/bash

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

gdzie server_namejest nazwa twojego serwera Emacs i my-update-envjest funkcją zdefiniowaną przez twój ~/.emacsplik:

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

Teraz możesz po prostu pisać update_emacs_envw wierszu poleceń powłoki, aby zaktualizować zmienne środowiskowe Emacsa.

Håkon Hægland
źródło
I można również uruchomić „printenv” z wnętrza funkcji ...
mankoff,
@mankoff Właściwie myślę, że nie mogłeś .. :) (Wydrukowałby wtedy stare wartości)
Håkon Hægland
Nie możesz odrodzić powłoki z flagą logowania? Lub source.bashrc, .bash_profile itp.?
mankoff
Tak .. ale nie pomogłoby to w specjalnym przypadku, jeśli eksportuję do powłoki bezpośrednio z wiersza poleceń, używającexport VAR=value
Håkon Hægland
Tak, nie myślałem o tej sprawie. Eleganckie rozwiązanie z klientem!
mankoff
3

Użyłem tego:

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
}

Pozwala wyeksportować nazwaną zmienną, EG:

export EDITOR=vim
export-emacs EDITOR
Phil Jackson
źródło