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")

Другие вопросы по тегам