Emacs игнорирует мой путь при запуске команды компиляции
Вопрос
Я пытаюсь запустить команду компиляции (rake огурец) с определенной версией 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
.
Есть идеи?
Решение
Небольшая модификация решения от 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, и правильный путь уже передан в оболочку, запущенную командой компиляции!Так что же дает?Вот ответ:
В MacOS X есть небольшой инструмент под названием path_helper(1)
.По умолчанию он вызывается из /etc/profile
, который выполняется Bash при запуске оболочки.Когда вы запускаете компиляцию из Emacs, она запускает оболочку (по умолчанию это Bash в MacOS X) и, следовательно, выполняет это path_helper
инструмент.И вот ключевой момент: path_helper
меняет твой путь, перемещая стандартные каталоги типа /usr/bin
перед добавленными вами каталогами, независимо от того, куда вы их изначально добавили.Попробуйте это сами, открыв оболочку и сначала взглянув, что такое PATH, а затем выполнив /usr/lib/path_helper
и посмотрите на полученный PATH!
Решением грубой силы для вас может быть просто закомментировать вызов path_helper
в /etc/profile
.Однако обратите внимание, что тогда вы не получите автоматически пути в /etc/paths.d
настройка по path_helper
, что является основной целью инструмента.
У меня нет Mac, поэтому я не могу проверить это напрямую, но все это можно найти на странице *информация*. Интерактивная нижняя оболочка.
Когда вы запускаете оболочку в 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
- это просто список каталогов Эмакс используется для поиска исполняемых программ.На поведение исполняемых файлов не влияют изменения в 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;в других версиях не пробовал, но ожидаю, что это сработает.)
попробуйте это, может быть.замените строку пути на свою.
(добавление в список «путь загрузки «~/opt/swank-clojure/src/emacs»)
Насколько я заметил, Emacs берет переменную пути из оболочки, из которой он запущен, поэтому одним из решений является изменение $PATH в оболочке перед запуском Emacs.
Еще один подход, который я использовал, более гибкий, заключается в использовании Makefile и добавлении «source ~/script_that_set_path» перед каждой имеющейся у вас командой make.
Я пробовал так много разных подходов к этому, что в итоге не использовал emacs для настройки среды команд компиляции.
Сейчас я создаю файл run_helper.sh, который просто инициализирует чистую среду, а затем использует exec $*
выполнить команду, переданную в качестве аргумента run_helper.sh
Этот run_helper.sh
обычно зависит от проекта, но я сохраняю шаблон, который использую для начала при создании нового проекта.
Тогда я просто бегу compile
из emacs, например bash run_helper.sh rspec path/to/tests
например.
Если я использую это для запуска тестов Ruby, мой помощник инициализирует RVM для использования правильного Ruby и набора драгоценных камней.Если я использую какой-либо другой язык, он может просто экспортировать необходимые переменные среды или выполнить какую-либо другую инициализацию, но таким образом я могу сделать это в сценарии 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
который я не хочу загружать только для запуска некоторых тестов.
У меня это сработало с двумя вещами.
Сначала я последовал совету sanityinc
Улучшенная и модифицированная версия фрагмента кода теперь опубликована как библиотека elisp под названием exec-path-from-shell;устанавливаемые пакеты доступны в Marmalade и Melpa.
У меня все еще была проблема с командами компиляции.Валко Сипули прав: возникла проблема с path_helper.
Я прокомментировал соответствующую строку в /etc/profile, и это не помогло.Проблема все еще существует.Я использую не bash, а zsh.Немного покопавшись, я нашел /etc/zshenv.Этот файл также вызывает path_helper.
После комментария раздела path_helper в /etc/zshenv мой путь наконец-то стал правильным.