Emacs在运行编译命令时忽略了我的路径
我正在尝试使用我的Mac OS X系统上的特定ruby版本运行编译命令(rake cucumber),我使用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
选项来强制登录shell(读取.profile
或.bash_profile
),而不是交互式shell(只读取.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命令启动的shell! 什么赋予了什么? 这是答案:
在MacOS X中,有一个名为path_helper(1)
的小工具。 它默认从/etc/profile
调用,由shell启动时由Bash执行。 当您从Emacs开始编译时,它会启动一个shell(默认情况下是MacOS X上的Bash),因此执行此path_helper
工具。 关键点path_helper
: path_helper
重新排列路径 ,在自定义添加的目录前移动标准目录,如/usr/bin
,无论您最初添加它们的位置。 通过打开一个shell并首先查看PATH是什么来自己尝试一下,然后执行/usr/lib/path_helper
并查看生成的PATH!
您的powershell解决方案可能只是在/etc/profile
注释掉对path_helper
的调用。 但是请注意,然后您不会通过path_helper
自动获取/etc/paths.d
设置中的路径,这是该工具的主要用途。
我没有Mac,所以我无法直接测试,但这可以在* info *页面的Interactive Inferior Shell中找到 。
当您在Emacs中启动shell时,生成的进程是Emacs变量explicit-shell-file-name
(如果为nil
,则使用环境变量ESHELL
和SHELL
)。
然后它发送~/.emacs_*shellname*
(例如,如果你的shell是csh
,那么~/.emacs_csh
将被发送。另外, csh
程序的相应.rc文件来源,所以你可以更新为好吧(在我的情况下.cshrc
)。此外,您可以在.rc文件中包装自定义项,并检查环境变量INSIDE_EMACS
(Emacs在运行shell之前设置的变量)。
您需要更新这些文件以更改shell中的路径,而不是更改Emacs变量exec-path
。 exec-path
– 这只是Emacs用于查找可执行程序的目录列表。 exec-path
更改不会影响可执行文件的行为。
我发现Mac上的environment.plist方案非常难看,所以我使用以下代码片段,假设您希望Emacs使用您在Terminal.app中看到的相同PATH:
(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中适用于我;在其他版本中没有尝试过,但我希望它可以工作。)
试试吧。 用你的路径字符串替换。
(add-to-list’load-path“〜/ opt / swank-clojure / src / emacs”)
据我观察,Emacs从它启动的shell中获取路径变量,因此一种解决方案是在启动Emacs之前更改shell中的$ PATH。
我使用的另一种更灵活的方法是使用Makefile并在每个make命令前添加“source~ / script_that_set_path”。
我尝试了很多不同的方法,最终没有使用emacs来设置我的编译命令环境。
我现在做的是创建一个run_helper.sh文件,它只是初始化一个干净的环境,然后使用exec $*
来执行作为参数传递给run_helper.sh
的命令
这个run_helper.sh
通常是项目特定的,但我保留了一个模板,我在创建新项目时使用该模板。
然后我简单地从emacs中运行compile
,例如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
中有很多东西,我不想加载它来运行一些测试。
它有两件事对我有用。
首先,我遵循了sanityinc的建议
代码片段的改进和修改版本现在作为elisp库发布,名为exec-path-from-shell; Marmalade和Melpa提供可安装的包装
我仍然遇到编译命令的问题。 Valko Sipuli是对的,涉及path_helper的问题。
我评论了/ etc / profile中的相应行,但没有帮助。 还有问题。 我不使用bash而是使用zsh。 挖了一点我发现/ etc / zshenv。 该文件也调用path_helper。
在评论/ etc / zshenv中的path_helper部分后,我的路径终于正确了