Umgebungsvariablen neu laden

10

Diese Frage wurde bei Superuser gestellt. Es gibt eine Möglichkeit, Umgebungsvariablen in Emacs neu zu laden , aber es wurde keine gute Lösung angegeben.

Ich verwende EmacsClient mit häufig mehr als 30 geöffneten Puffern. Wenn ich eine Umgebungsvariable in der Shell ändere, muss ich EmacsClient beenden (und alle Puffer erneut öffnen) oder die Umgebungsvariable auch in Emacs manuell festlegen. Ich finde es ärgerlich, dass ich die Umgebungsvariablen in Emacs nicht einfach aktualisieren kann. Irgendwelche Vorschläge?

Håkon Hægland
quelle
Es gibt keine einfache Möglichkeit, dies zu tun, da das Ändern einer Umgebungsvariablen im übergeordneten Prozess ihren Wert nicht aktualisiert, wenn er in ein untergeordnetes Element exportiert wird.
Erik Hetzner

Antworten:

7

exec-path-from-shell stellt den exec-path-from-shell-copy-envBefehl bereit , mit dem Sie den Wert von Umgebungsvariablen in Emacs-Sitzungen kopieren können. Legt beispielsweise M-x exec-path-from-shell-copy-env RET FOOden Wert von auch $FOOin Emacs fest.

Beachten Sie, dass exec-path-from-shell-copy-enveine neue Shell erzeugt wird, um den Wert der Umgebungsvariablen zu extrahieren. Daher funktioniert es nur für Variablen, die Sie in Ihren Shell-Konfigurationsdateien festgelegt haben (z. B. .bashrc), nicht jedoch für Variablen, die nur in einer laufenden Shell-Sitzung mit festgelegt wurden export. Das Extrahieren dieser Variablen ist im Allgemeinen nicht ohne komplizierte Hacks möglich, die eine /proc/API oder eine ähnliche API zum Ausführen von Prozessen untersuchen.

Mondhorn
quelle
In Bezug auf die letzteren / vorübergehenden Werte wäre es einfach genug, die aktualisierten Werte direkt von dieser Shell an emacsclient weiterzuleiten, wenn Emacs als Server ausgeführt wird.
Phils
@phils Danke, siehe meine aktualisierte Antwort ..
Håkon Hægland
5

Als Problemumgehung kann Folgendes verwendet werden (Linux, Bash):

  • Führen Sie zuerst printenv -0 > env.txtdas Bash-Terminalfenster aus.
  • Dann renne aus Emacs heraus
(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)))))

Aktualisieren

Es stellt sich heraus, dass dies mit der --evalOption des emacsclientBefehls eleganter erfolgen kann : Definieren eines Bash-Skripts update_emacs_env:

#! /bin/bash

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

Wo server_nameist Ihr Emacs-Servername und my-update-enveine von Ihrer ~/.emacsDatei definierte Funktion :

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

Jetzt können Sie einfach update_emacs_envüber die Shell-Befehlszeile eingeben, um die Emacs-Umgebungsvariablen zu aktualisieren.

Håkon Hægland
quelle
Und Sie könnten das "printenv" auch von innerhalb der Funktion
ausführen
@mankoff Eigentlich denke ich, Sie könnten nicht .. :) (Es würde dann die alten Werte drucken)
Håkon Hægland
Kannst du keine Shell mit Login-Flag erzeugen? Oder sourcedas .bashrc, .bash_profile usw.?
Mankoff
Ja .. aber es würde für den Sonderfall nicht helfen, wenn ich in der Shell direkt von der Kommandozeile mitexport VAR=value
Håkon Hægland
Ja, an diesen Fall habe ich nicht gedacht. Elegante Lösung mit dem Kunden!
Mankoff
3

Ich habe das benutzt:

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
}

Ermöglicht das Exportieren einer benannten Variablen, EG:

export EDITOR=vim
export-emacs EDITOR
Phil Jackson
quelle