Emacs игнорирует мой путь, когда запускает команду компиляции
Я пытаюсь заставить команду compile (rake cucumber) работать с определенной версией ruby в моей системе Mac OS X. Я использую rvm, чтобы сделать это в настоящее время в терминале. Мой ~/.MacOSX/environment.plist содержит правильный путь, но emacs настаивает на том, чтобы предварять этот путь и поэтому делать его бесполезным. Я также попробовал:
(when (equal system-type 'darwin)
(setenv "PATH" (concat "/Users/fearoffish/.rvm/bin:/Users/fearoffish/.rvm/rubies/ruby-1.8.7-p249/bin:/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249/bin:/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249%global/bin:/Users/fearoffish/.rvm/bin"))
(push "/Users/fearoffish/.rvm/bin" exec-path)
(push "/Users/fearoffish/.rvm/rubies/ruby-1.8.7-p249/bin" exec-path)
(push "/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249/bin" exec-path)
(push "/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249%global/bin" exec-path)
(push "/Users/fearoffish/.rvm/bin" exec-path))
Это была отчаянная попытка новичка Emacs получить то, что я хотел. Он все еще стоит перед ним, так что мой путь заканчивается:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/Users/fearoffish/.rvm/bin:/Users/fearoffish/.rvm/rubies/ruby-1.8.7-p249/bin:/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249/bin:/Users/fearoffish/.rvm/gems/ruby-1.8.7-p249%global/bin
Я не хочу, чтобы / usr / bin и другие предваряли, я хочу, чтобы мой путь был первым, а путь к файлу emacs был в конце, я думаю, это решило бы мою проблему.
Я проверяю это, просто открыв Aquamacs и запустив meta-x compile
а потом echo $PATH
,
Есть идеи?
8 ответов
Небольшая модификация решения от sanityinc (не удалось найти способ ввести его в комментарии выше - это только я?)
- я использую
-l
опция для оболочки, чтобы заставить оболочку входа в систему (который читает.profile
или же.bash_profile
), а не интерактивная оболочка (которая читает только.bashrc
). - Я делаю некоторую обрезку строки в возвращаемом пути (поскольку проверка показывает пробивающуюся новую строку).
Модифицированный код:
(defun set-exec-path-from-shell-PATH ()
(let ((path-from-shell
(replace-regexp-in-string "[[:space:]\n]*$" ""
(shell-command-to-string "$SHELL -l -c 'echo $PATH'"))))
(setenv "PATH" path-from-shell)
(setq exec-path (split-string path-from-shell path-separator))))
(when (equal system-type 'darwin) (set-exec-path-from-shell-PATH))
Кажется, что все неправильно поняли исходную проблему: путь уже настроен правильно в Emacs, и правильный путь уже передан оболочке, запущенной командой compile! Так что же дает? Вот ответ:
В MacOS X есть небольшой инструмент под названием path_helper(1)
, Он вызывается по умолчанию из /etc/profile
, который выполняется Bash при запуске оболочки. Когда вы запускаете компиляцию из Emacs, он запускает оболочку (по умолчанию это Bash в MacOS X) и поэтому выполняет это path_helper
инструмент. И здесь наступает ключевой момент: path_helper
перестраивает ваш путь, перемещая стандартные каталоги, такие как /usr/bin
перед вашими пользовательскими добавленными каталогами, независимо от того, где вы изначально добавили их. Попробуйте сами, открыв оболочку и сначала посмотрев, что такое PATH, а затем выполните /usr/lib/path_helper
и посмотрите на полученный путь!
Решение проблемы грубой силы может заключаться в том, чтобы просто закомментировать призыв к path_helper
в /etc/profile
, Обратите внимание, что тогда вы не сможете автоматически получить пути в /etc/paths.d
настройка по path_helper
, которая является основным назначением инструмента.
У меня нет Mac, поэтому я не могу проверить это напрямую, но все это можно найти на странице *info* Interactive Inferior Shell.
Когда вы запускаете оболочку в Emacs, порождаемый процесс - это программа в переменной Emacs. explicit-shell-file-name
(и если это nil
переменные среды ESHELL
а также SHELL
используются).
Затем он отправляет содержимое ~/.emacs_*shellname*
(например, если ваша оболочка csh
, затем ~/.emacs_csh
будет отправлен Кроме того, соответствующие файлы.rc для csh
Программа поставлена, так что вы можете обновить это (в моем случае .cshrc
). Кроме того, вы можете обернуть настройки в файле.rc проверкой переменной среды INSIDE_EMACS
(который устанавливает Emacs до запуска оболочки).
Вам нужно обновить эти файлы, чтобы изменить путь в оболочке, а не переменную Emacs exec-path
, exec-path
- это просто список каталогов, которые Emacs использует для поиска исполняемых программ. На поведение исполняемых файлов не влияют изменения exec-path
,
Я нахожу схему environment.plist на Mac довольно уродливой, поэтому я использую следующий фрагмент, который предполагает, что вы хотите, чтобы Emacs использовал тот же PATH, который вы видите в вашем Terminal.app:
(defun set-exec-path-from-shell-PATH () (let ((path-from-shell (shell-command-to-string "$SHELL -i -c 'echo $PATH'"))) (setenv "PATH" path-from-shell) (setq exec-path (split-string path-from-shell path-separator))))
(Это работает для меня в Emacs 23; я не пробовал его в других версиях, но я ожидаю, что это сработает.)
Я пробовал так много разных подходов к этому, что в итоге не использовал emacs для настройки моей командной среды компиляции.
Сейчас я создаю файл run_helper.sh, который просто инициализирует чистую среду и затем использует exec $*
выполнить команду, переданную в качестве аргумента run_helper.sh
это run_helper.sh
обычно зависит от проекта, но я сохраняю шаблон, который использую для начала при создании нового проекта.
Тогда я просто бегу compile
из Emacs, как bash run_helper.sh rspec path/to/tests
например.
Если я использую это для запуска тестов ruby, мой помощник инициализирует RVM, чтобы использовать правильный ruby и gemset. Если я использую какой-то другой язык, он может просто экспортировать необходимые переменные окружения или выполнить какую-то другую инициализацию, но таким образом я могу сделать это в скрипте bash, вместо того, чтобы всегда связываться с путями emacs и elisp каждый раз, когда я запускаю новый проект.
Вот пример run_helper.sh
файл
#!/bin/bash
cd /Users/simao/Documents/sp
export DYLD_LIBRARY_PATH="/usr/local/mysql/lib:$DYLD_LIBRARY_PATH"
source "$HOME/.rvm/scripts/rvm" # This loads the proper ruby and gemset from .rvmrc
export RAILS_ENV=test
exec $*
Это также заставляет мои тесты работать быстрее, потому что у меня есть много вещей в моем .zshrc
что я не хочу загружаться только для запуска некоторых тестов.
Насколько я заметил, Emacs берет переменную пути из оболочки, из которой он запущен, поэтому одним из решений является изменение $PATH в оболочке перед запуском Emacs.
Еще один подход, который я использовал, который является более гибким, - это использование Makefile и добавление "source ~/script_that_set_path" перед каждой вашей командой make.
У меня сработало две вещи.
Сначала я последовал совету sanityinc
Улучшенная и измененная версия фрагмента кода теперь публикуется как библиотека elisp, которая называется exec-path-from-shell; Устанавливаемые пакеты доступны в Marmalade и Melpa
У меня все еще была проблема с командами компиляции. Валько Сипули прав, там была проблема, связанная с path_helper.
Я прокомментировал соответствующую строку в /etc/profile, и это не помогло. Проблема все еще там. Я не использую Bash, но Zsh. Немного покопавшись я нашел /etc/zshenv. Этот файл также вызывает path_helper.
После комментирования раздела path_helper в / etc / zshenv мой путь, наконец, правильный
Попробуйте это возможно. замените строку пути на вашу.
(add-to-list 'путь загрузки' ~/opt/swank-clojure/src/emacs")