exec-path e $ PATH


28

Ho visto esempi online in cui le persone aggiungono percorsi al percorso predefinito in Emacs con:

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

Sono nuovo di Elisp e penso di capire cosa fa la dichiarazione sopra, ma ho alcune domande:

  • In quale ordine Emacs cerca i percorsi di esecuzione? Ad esempio, considera il valore di $PATH(variabile ambientale) (e in tal caso, prima o dopo exec-path?)

  • Come posso anteporre più di questi percorsi? Posso continuare a concatenarli? per esempio

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

    o dovrei fare:

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

Ho anche trovato questo interessante pacchetto su GitHub: exec-path-from-shell . Perché è necessario un pacchetto per questo?

Motivazione

Hai mai scoperto che un comando funziona nella tua shell, ma non in Emacs?

Questo succede molto su OS X, dove un'istanza di Emacs avviata dalla GUI eredita un set predefinito di variabili d'ambiente.

Questa libreria funziona risolve questo problema copiando importanti variabili d'ambiente dalla shell dell'utente: funziona chiedendo alla shell di stampare le variabili di interesse, quindi copiandole nell'ambiente Emacs.


3
Benvenuti in Emacs ed Elisp! Sono ancora abbastanza fresco con l'argomento da solo e non conosco le risposte alle tue domande, ma ho pensato di menzionare qualcosa che ha reso la vita molto più facile: le funzioni di descrizione. eg (describe-function 'add-to-list)( C-h f) ti fornirà il documento per la add-to-listfunzione, nonché i collegamenti alla fonte. C'è anche (describe-variable 'exec-path)( C-h v). Questo non vuole essere un commento RTFM: questi documenti non rispondono a tutte le domande che hai elencato, solo qualcosa di utile.
jtmoulia,

Grazie @jtmoulia! Lo terrò sicuramente a mente per domande future.
Amelio Vazquez-Reina,

Inoltre C-h v exec-path, utilizzare i manuali (Emacs ed Elisp). In un manuale, i exec-pathti indirizza a una spiegazione utile. Chiedi prima a Emacs : non ti dispiacerà.
Disegnò il

Risposte:


23

1) PATHeexec-path

Emacs imposta exec-pathdal valore di PATHall'avvio, ma non lo guarderà più in seguito. Ma se si esegue un comando, questo erediterà PATH, no exec-path, quindi i sottoprocessi possono trovare comandi diversi da quelli di Emacs.

Come dice Francesco, questo può essere particolarmente confuso shell-command, in quanto non esegue direttamente un processo, ma chiama una shell per eseguirlo, che utilizzerà PATH, non exec-path.

2) Aggiunta di più percorsi a exec-path

Chiama add-to-listripetutamente:

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

Nota che add-to-listaggiunge all'inizio dell'elenco, quindi questo finirà con l' "PATH2"essere nel exec-pathprecedente "PATH1".

Puoi anche utilizzare un accesso più "basso livello" agli elenchi:

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

Questo aggiungerà "PATH1"e "PATH2"al tuo exec-path, in questo ordine.

3) PERCORSO di Mac OS

Il problema su Mac OS X è che Mac OS non imposta l'ambiente allo stesso modo quando si chiama un programma dall'interfaccia utente globale o quando lo si chiama da una shell. Ciò significa che l'esecuzione di Emacs da una shell comporterà l'impostazione di variabili di ambiente diverse rispetto a quando lo si esegue dal finder. Ciò è particolarmente fastidioso se si impostano variabili di ambiente .bashrco simili, poiché ciò non influirà sugli Emac "globali".

Apparentemente il pacchetto avvia una shell e importa le variabili d'ambiente da lì, imitando l'ambiente che si ottiene da una shell in un Emacs avviato a livello globale.


Grazie Jorgen. Riguardo a Q3: ti capita di sapere dove PATHè definito il valore predefinito per i programmi avviati dall'interfaccia utente globale (ambiente desktop)? Sto riscontrando lo stesso problema con PYTHONPATHin elpy:). Quando avvio Emacs dal desktop, Emacs non è a conoscenza delle mie PYTHONPATHdefinizioni nel mio .zshenvfile (un file init per zsh), il che è molto frustrante, poiché elpynon sa quindi dove trovare i miei pacchetti Python. Sono felice di spostare queste PYTHONPATHdefinizioni in un diverso initfile shell (anche se idealmente vorrei che Emacs usasse le definizioni dal mio .zshenv)
Amelio Vazquez-Reina,

Temo di non sapere molto di Mac OS X. Un rapido google mi ha portato a stackoverflow.com/questions/135688/… che sembra indicare che launchd.conf è il posto giusto. Se tutto ciò che serve per questo è Emacs, è possibile naturalmente solo impostare sia exec-pathe PATHnella vostra .emacs. Puoi impostare PATHusando (setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH"))).
Jorgen Schäfer,

Grazie. So che la seguente Q si discosta leggermente dall'OP, ma c'è un modo per specificare in Emacs PYTHONPATHciò che elpydovrebbe usare?
Amelio Vazquez-Reina,

È possibile modificare process-environment, ad esempio utilizzando setenv. Puoi farlo in elpy-mode-hook, ma è una variabile globsl e renderlo buffer-local può facilmente portare a comportamenti confusi.
Jorgen Schäfer,

9

Quando emacs avvia un nuovo processo esterno usando funzioni primitive come call-processo start-process, viene eseguita la ricerca nell'eseguibile exec-path(e non $PATH)

Tuttavia, una funzione come shell-commandavvia la shell come sottoprocesso e gli passa il comando che si desidera eseguire. Per eseguire questo comando, la shell tenterà quindi di trovare l'eseguibile in $PATH(e non in exec-path).

Pertanto, exec-pathè ciò che conta di più per i processi esterni che sono avviati da Emacs stesso, mentre $PATHè ciò che conta per i comandi che esegui tu stesso con una funzione di livello superiore (usando M-!ad esempio)


Se si desidera aggiungere più directory a exec-path, è necessario utilizzare add-to-listpiù volte.

Puoi farlo manualmente

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

o usando un loop

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

Per quanto riguarda la tua terza domanda, se emacs è stato lanciato dall'ambiente desktop, eredita l'ambiente da esso, che potrebbe essere meno completo di quello di una shell completa.

Ciò significa che a volte potrebbe essere necessario completare il valore di Emacs per l' $PATHutilizzo di ciò che vede una shell normale. Questo è lo scopo della exec-path-from-shellbiblioteca di cui parli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.