exec-шлях та $ PATH


28

Я бачив приклади в Інтернеті, де люди додають шляхи до шляху за замовчуванням у Emacs за допомогою:

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

Я новачок у Елісп, і, думаю, я розумію, що робить твердження вище, але у мене є кілька питань:

  • У якому порядку Emacs здійснює пошук через контури виконання? Наприклад, чи враховує воно взагалі значення $PATH(змінної env.) (І якщо так, до чи після exec-path?)

  • Як я можу додати кілька таких шляхів? Чи можу я просто продовжувати їх об'єднувати? напр

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

    або мені робити:

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

Я також знайшов цей цікавий пакет на GitHub: exec-path-from-shell . Чому для цього потрібен пакет?

Мотивація

Ви коли-небудь виявите, що команда працює у вашій оболонці, а не в Emacs?

Це трапляється багато в OS X, коли екземпляр Emacs, запущений з графічного інтерфейсу, успадковує набір змінних середовища за замовчуванням.

Ця бібліотечна робота вирішує цю проблему, копіюючи важливі змінні середовища з оболонки користувача: вона працює, вимагаючи від вашої оболонки роздрукувати цікаві змінні, потім скопіювавши їх у середовище Emacs.


3
Ласкаво просимо до Emacs та Elisp! Я все ще досить свіжий з тією темою і не знаю відповідей на ваші запитання, але я подумав, що я згадаю щось, що полегшило життя набагато простіше: функції опису. наприклад (describe-function 'add-to-list)( C-h f) дасть вам документ про add-to-listфункцію, а також посилання на джерело. Там також (describe-variable 'exec-path)( C-h v). Це не означає, що це коментар RTFM - ці документи не відповідають на всі перелічені вами питання, а лише щось корисне.
jtmoulia

Дякую @jtmoulia! Я обов'язково маю це на увазі для майбутніх питань.
Амеліо Васкес-Рейна

На додаток до цього C-h v exec-pathкористуйтеся посібниками (Emacs та Elisp). У посібнику i exec-pathспрямовано на корисне пояснення. Спершу запитайте Emacs - ви не пошкодуєте, що зробили.
Дрю

Відповіді:


23

1) PATHіexec-path

Emacs встановлює exec-pathзначення при PATHзапуску, але пізніше його не перегляне. Але якщо ви запускаєте команду, вона успадковується PATH, ні exec-path, тому підпроцеси можуть знаходити різні команди, ніж Emacs.

Як каже Франческо, це може бути особливо заплутаним shell-command, оскільки це не запускає процес безпосередньо, а закликає оболонку для його запуску, яка використовуватиме PATH, а не exec-path.

2) Додавання кількох шляхів до exec-path

Просто дзвоніть add-to-listкілька разів:

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

Зверніть увагу, що add-to-listдодає до початку списку, так що це в кінцевому підсумку опиниться "PATH2"в exec-pathпопередньому "PATH1".

Ви також можете використовувати більше "низького рівня" доступу до списків:

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

Це додасть "PATH1"і "PATH2"до вашого exec-path, у цьому порядку.

3) PATH Mac OS

Проблема в Mac OS X полягає в тому, що Mac OS не встановлює оточення таким же чином, коли ви викликаєте програму з глобального інтерфейсу або коли ви викликаєте її з оболонки. Це означає, що запуск Emacs з оболонки призведе до встановлення різних змінних оточення, ніж коли ви запускаєте його з пошуку. Це особливо дратує, якщо ви встановлюєте змінні середовища у .bashrcподібних або подібних, оскільки це не вплине на "глобальні" Emacs.

Пакет, мабуть, запускає оболонку і імпортує змінні середовища звідти, імітуючи середовище, яке ви отримуєте від оболонки в Emacs, розпочатому глобально.


Спасибі Йорген. Щодо Q3: Чи трапляється вам знати, де PATHвизначено за замовчуванням програми, запущені з глобального інтерфейсу (робочого середовища)? У мене однакова проблема PYTHONPATHв elpy:). Коли я запускаю Emacs з робочого столу, Emacs не знає моїх PYTHONPATHвизначень у моєму .zshenvфайлі (файл init для zsh), що дуже засмучує, оскільки elpyне знає, де знайти мої пакети Python. Я радий перенести ці PYTHONPATHвизначення у інший initфайл оболонки (хоча в ідеалі я хотів би, щоб Emacs використовував визначення з моїх .zshenv)
Amelio Vaqueque-Reina

Боюся, я зовсім не знаю про Mac OS X. Швидкий google завів мене на stackoverflow.com/questions/135688/…, який, схоже, вказує на те, що startd.conf - це правильне місце. Якщо для цього вам потрібно лише Emacs, ви, звичайно, можете просто встановити і своє, exec-pathі PATHсвоє .emacs. Ви можете встановити PATHза допомогою (setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH"))).
Jorgen Schäfer

Спасибі. Я знаю, що наступні питання Q трохи розходяться з ОП, але чи можна в Emacs вказати, PYTHONPATHщо elpyслід використовувати?
Амеліо Васкес-Рейна

Ви можете змінювати process-environment, наприклад, використовуючи setenv. Це можна зробити в elpy-mode-hook, але це змінна globsl, і перетворення його на локальний буфер може легко призвести до заплутаної поведінки.
Jorgen Schäfer

9

Коли emacs запускає новий зовнішній процес за допомогою примітивних функцій, таких як, call-processабо start-processвиконується пошук у exec-path(а не $PATH)

Однак така функція, як shell-commandзапуск оболонки як підпроцес і передає їй команду, яку потрібно запустити. Для того, щоб виконати цю команду, оболонка буде намагатися знайти виконуваний файл у $PATH(а не в exec-path).

Отже, exec-pathсаме те, що найбільше враховує для зовнішніх процесів, які запускаються самим emacs, тоді $PATHяк те, що рахується для команд, які ви виконуєте за допомогою функції вищого рівня (використовуючи, M-!наприклад)


Якщо ви хочете додати кілька каталогів exec-path, вам слід скористатися add-to-listдекількома разів.

Це можна зробити вручну

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

або за допомогою циклу

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

Що стосується вашого третього запитання, якщо emacs був запущений із середовища робочого столу, він успадковує середовище від нього, яке може бути менш повним, ніж повне оболонка.

Це означає, що іноді може знадобитися заповнити значення Emacs для $PATHвикористання того, що бачить звичайна оболонка. Це мета exec-path-from-shellбібліотеки, яку ви згадуєте.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.