Я видел примеры онлайн, где люди добавляют пути к пути по умолчанию в Emacs с помощью:
(add-to-list 'exec-path "/usr/local/bin/")
Я новичок в Elisp и думаю, что понимаю, что делает приведенное выше утверждение, но у меня есть несколько вопросов:
В каком порядке Emacs ищет пути выполнения? Например, учитывает ли он значение
$PATH
(env. Variable) вообще (и если да, то до или после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, запущенный из GUI, наследует набор переменных среды по умолчанию.
Эта библиотека решает эту проблему путем копирования важных переменных среды из оболочки пользователя: она запрашивает у вашей оболочки печать переменных, представляющих интерес, а затем копирует их в среду Emacs.
(describe-function 'add-to-list)
(C-h f
) даст вам документ дляadd-to-list
функции, а также ссылки на источник. Там также(describe-variable 'exec-path)
(C-h v
). Это не комментарий RTFM - эти документы не отвечают на все вопросы, которые вы перечислили, просто что-то полезное.C-h v exec-path
, используйте руководство (я) (Emacs и Elisp). В руководстве,i exec-path
направляет вас к полезному объяснению. Сначала спросите Emacs - вы не пожалеете, что сделали.Ответы:
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
добавляет к началу списка, так что в конечном итоге это будет"PATH2"
вexec-path
предыдущем"PATH1"
.Вы также можете использовать более низкоуровневый доступ к спискам:
Это добавит
"PATH1"
и"PATH2"
к вамexec-path
, в таком порядке.3) Путь Mac OS '
Проблема в Mac OS X состоит в том, что Mac OS не устанавливает среду одинаково, когда вы вызываете программу из глобального пользовательского интерфейса или когда вы вызываете ее из оболочки. Это означает, что запуск Emacs из оболочки приведет к тому, что будут установлены переменные окружения, отличные от тех, которые вы запускаете из Finder. Это особенно раздражает, если вы устанавливаете переменные окружения
.bashrc
или подобные, так как это не повлияет на «глобальные» Emacs.По всей видимости, пакет запускает оболочку и импортирует оттуда переменные среды, имитируя среду, которую вы получаете из оболочки в глобально запущенном Emacs.
источник
PATH
задано значение по умолчанию для программ, запускаемых из глобального пользовательского интерфейса (среды рабочего стола)? У меня та же проблема сPYTHONPATH
вelpy
:). Когда я запускаю Emacs с рабочего стола, Emacs не знает о моихPYTHONPATH
определениях в моем.zshenv
файле (файл инициализации дляzsh
), что очень расстраивает, такelpy
как не знает, где найти мои пакеты Python. Я счастлив перенести этиPYTHONPATH
определения в другойinit
файл оболочки (хотя в идеале я хотел бы, чтобы Emacs использовал определения из моего.zshenv
)exec-path
иPATH
в вашем.emacs
. Вы можете установитьPATH
с помощью(setenv "PATH" (format "%s:%s" "/new/path/element" (getenv "PATH")))
.PYTHONPATH
чтоelpy
следует использовать?process-environment
, например, используяsetenv
. Вы можете сделать это внутриelpy-mode-hook
, но это переменная globsl, и ее локальное расположение в буфере может легко привести к путанице.Когда emacs запускает новый внешний процесс, используя примитивные функции, такие как
call-process
илиstart-process
, исполняемый файл ищетсяexec-path
(а не$PATH
)Однако такая функция, как
shell-command
запускает оболочку как подпроцесс и передает ей команду, которую вы хотите запустить. Чтобы выполнить эту команду, оболочка попытается найти исполняемый файл в$PATH
(а не вexec-path
).Следовательно, именно это
exec-path
имеет значение для внешних процессов, запускаемых самим emacs, тогда$PATH
как для команд, которые вы запускаете самостоятельно с помощью функции более высокого уровня ( M-!например,)Если вы хотите добавить несколько каталогов
exec-path
, вы должны использоватьadd-to-list
несколько раз.Вы можете сделать это вручную
или используя цикл
Что касается вашего третьего вопроса, если emacs был запущен из среды рабочего стола, он наследует от него среду, которая может быть менее полной, чем у полной оболочки.
Это означает, что иногда может потребоваться заполнить значение Emacs для
$PATH
использования того, что видит обычная оболочка. Это цельexec-path-from-shell
библиотеки, которую вы упоминаете.источник