exec-path und $ PATH

28

Ich habe Beispiele online gesehen, in denen Leute dem Standardpfad in Emacs Pfade hinzufügen mit:

(add-to-list 'exec-path "/usr/local/bin/")

Ich bin neu bei Elisp und ich denke, ich verstehe, was die obige Aussage bewirkt, aber ich habe ein paar Fragen:

  • In welcher Reihenfolge durchsucht Emacs die Ausführungspfade? Berücksichtigt es beispielsweise den Wert von $PATH(Umgebungsvariable) überhaupt (und wenn ja, davor oder danach exec-path?)

  • Wie kann ich mehrere solcher Pfade voranstellen ? Kann ich sie einfach weiter verketten? z.B

    (add-to-list 'exec-path "PATH1", "PATH2")
    

    oder soll ich tun:

    (add-to-list 'exec-path "PATH1:PATH2:PATH3") 
    

Ich fand dieses interessante Paket auch auf GitHub: exec-path-from-shell . Warum braucht man dafür ein Paket?

Motivation

Finden Sie jemals heraus, dass ein Befehl in Ihrer Shell funktioniert, aber nicht in Emacs?

Dies passiert häufig unter OS X, wo eine über die GUI gestartete Emacs-Instanz einen Standardsatz von Umgebungsvariablen erbt.

Diese Bibliothek löst dieses Problem, indem sie wichtige Umgebungsvariablen aus der Shell des Benutzers kopiert: Sie fordert Ihre Shell auf, die gewünschten Variablen auszudrucken und sie dann in die Emacs-Umgebung zu kopieren.

Amelio Vazquez-Reina
quelle
3
Willkommen bei Emacs und Elisp! Ich bin immer noch ziemlich frisch mit dem Thema und kenne die Antworten auf Ihre Fragen nicht, aber ich dachte, ich würde etwas erwähnen, das das Leben sehr viel einfacher gemacht hat: die Beschreibungsfunktionen. eg (describe-function 'add-to-list)( C-h f) gibt Ihnen das Dokument für die add-to-listFunktion sowie Links zur Quelle. Es gibt auch (describe-variable 'exec-path)( C-h v). Dies ist kein RTFM-Kommentar. Diese Dokumente beantworten nicht alle Fragen, die Sie aufgeführt haben, sondern sind nur nützlich.
Jtmoulia
Vielen Dank @jtmoulia! Ich werde das auf jeden Fall für zukünftige Fragen im Hinterkopf behalten.
Amelio Vazquez-Reina
Zusätzlich zu C-h v exec-path, verwenden Sie die manuelle (n) (Emacs und Elisp). i exec-pathLeitet Sie in einem Handbuch zu einer hilfreichen Erklärung. Fragen Sie zuerst Emacs - Sie werden es nicht bereuen.
Drew

Antworten:

23

1) PATHundexec-path

Emacs setzt exec-pathden Wert von PATHbeim Start ab, wird ihn aber später nicht erneut betrachten. Wenn Sie jedoch einen Befehl ausführen, wird dieser erben PATH, nicht exec-path, sodass Unterprozesse andere Befehle finden können als Emacs.

Wie Francesco sagt, kann dies besonders verwirrend sein shell-command, da dies keinen Prozess direkt ausführt, sondern eine Shell aufruft, um ihn auszuführen, die dies jedoch PATHnicht verwendet exec-path.

2) Hinzufügen mehrerer Pfade zu exec-path

Rufen Sie einfach add-to-listwiederholt an:

(add-to-list 'exec-path "PATH1")
(add-to-list 'exec-path "PATH2")

Beachten Sie, dass dies add-to-listam Anfang der Liste steht, so dass es sich letztendlich um "PATH2"das exec-pathVorherige handelt "PATH1".

Sie können auch mehr "Low-Level" -Zugriff auf Listen verwenden:

(setq exec-path (append '("PATH1" "PATH2")
                        exec-path))

Dies fügt "PATH1"und "PATH2"zu Ihrer hinzu exec-path, in dieser Reihenfolge.

3) Mac OS-PFAD

Das Problem unter Mac OS X ist, dass Mac OS die Umgebung nicht gleich einstellt, wenn Sie ein Programm von der globalen Benutzeroberfläche oder von einer Shell aus aufrufen. Das bedeutet, dass beim Ausführen von Emacs von einer Shell aus andere Umgebungsvariablen festgelegt werden als beim Ausführen über den Finder. Dies ist besonders ärgerlich, wenn Sie Umgebungsvariablen .bashrcoder ähnliches setzen, da dies keinen Einfluss auf den "globalen" Emacs hat.

Das Paket startet anscheinend eine Shell und importiert Umgebungsvariablen von dort und ahmt die Umgebung nach, die Sie von einer Shell in einem global gestarteten Emacs erhalten.

Jorgen Schäfer
quelle
Danke Jörgen. Zu F3: Wissen Sie zufällig, wo die Standardeinstellung PATHfür Programme definiert ist, die über die globale Benutzeroberfläche (Desktop-Umgebung) gestartet wurden? Ich habe das gleiche Problem mit PYTHONPATHin elpy:). Wenn ich Emacs vom Desktop aus starte, sind Emacs meine PYTHONPATHDefinitionen in meiner .zshenvDatei (eine Init-Datei für zsh) nicht bekannt, was sehr frustrierend ist, da elpyich dann nicht weiß, wo ich meine Python-Pakete finde. Ich bin froh, diese PYTHONPATHDefinitionen in eine andere Shell- initDatei zu verschieben (obwohl ich Emacs im Idealfall bitten würde, die Definitionen aus meiner zu verwenden .zshenv)
Amelio Vazquez-Reina
Ich fürchte, ich weiß überhaupt nicht viel über Mac OS X. Ein kurzer Google- Aufruf brachte mich zu stackoverflow.com/questions/135688/…, was darauf hinzudeuten scheint, dass launchd.conf der richtige Ort ist. Wenn Sie dafür nur Emacs benötigen, können Sie natürlich sowohl exec-pathals auch PATHin Ihren einstellen .emacs. Sie können einstellen , PATHverwenden (setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH"))).
Jorgen Schäfer
Vielen Dank. Ich weiß, dass das folgende Q ein bisschen vom OP abweicht, aber gibt es eine Möglichkeit, in Emacs anzugeben PYTHONPATH, welches verwendet werden elpysoll?
Amelio Vazquez-Reina
Sie können process-environmentzum Beispiel mit ändern setenv. Sie können dies tun elpy-mode-hook, aber es ist eine globsl-Variable, und wenn Sie sie pufferlokal machen, kann dies leicht zu verwirrendem Verhalten führen.
Jorgen Schäfer
9

Wenn emacs einen neuen externen Prozess mit primitiven Funktionen wie call-processoder startet start-process, wird die ausführbare Datei durchsucht exec-path(und nicht $PATH)

Eine Funktion wie shell-commandstartet die Shell jedoch als Unterprozess und übergibt ihr den Befehl, den Sie ausführen möchten. Um diesen Befehl auszuführen, versucht die Shell, die ausführbare Datei in $PATH(und nicht in exec-path) zu finden.

exec-pathFür externe Prozesse, die von emacs selbst gestartet werden , zählt daher am meisten, während $PATHfür Befehle, die Sie selbst mit einer übergeordneten Funktion ausführen ( M-!z. B. mithilfe von), das gilt.


Wenn Sie mehrere Verzeichnisse hinzufügen möchten exec-path, sollten Sie add-to-listmehrere Male verwenden.

Sie können es entweder manuell tun

(add-to-list 'exec-path "dir1")
(add-to-list 'exec-path "dir2")

oder mit einer Schleife

(dolist (dir '("dir1" "dir2"))
  (add-to-list 'exec-path dir))

Was Ihre dritte Frage betrifft, wenn Emacs über die Desktop-Umgebung gestartet wurde, erbt es die Umgebung, die möglicherweise weniger vollständig ist als die einer vollständigen Shell.

Dies bedeutet, dass es manchmal erforderlich sein kann, den Wert von Emacs zu vervollständigen, um das zu $PATHverwenden, was eine reguläre Shell sieht. Dies ist der Zweck der exec-path-from-shellBibliothek, die Sie erwähnen.

ffevotte
quelle