Emacs在运行编译命令时忽略了我的路径

时间:2022-04-09 23:02:30

I'm trying to get a compile command (rake cucumber) to run with a specific ruby version on my Mac OS X system, I use rvm to do this currently in the terminal. My ~/.MacOSX/environment.plist has the correct path in it, but emacs insists on prepending to this path and therefore making it useless. I've also tried:

我正在尝试使用我的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))

It was the desperate attempt of an emacs beginner to get what I wanted. It still prepends in front of it, so my path ends up being:

这是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

I don't want /usr/bin and others prepending, I want my path first and the emacs prepended path to be at the end, I reckon this would fix my problem.

我不希望/ usr / bin和其他人在前面,我希望我的路径首先和emacs前置路径到最后,我认为这将解决我的问题。

I test this by simply opening Aquamacs and running meta-x compile and then echo $PATH.

我通过简单地打开Aquamacs并运行meta-x编译然后回显$ PATH来测试它。

Any ideas?

有任何想法吗?

8 个解决方案

#1


9  

A small modification to the solution by sanityinc (couldn't find a way to enter it in the comments above -- is that just me?)

sanityinc对解决方案的一个小修改(在上面的评论中找不到输入它的方法 - 只有我吗?)

  • I use -l option to the shell to force a login shell (which reads .profile or .bash_profile), rather than an interactive shell (which only reads .bashrc).
  • 我使用-l选项来强制登录shell(读取.profile或.bash_profile),而不是交互式shell(只读取.bashrc)。
  • I do some string trimming on the returned path (as inspection shows a newline sneaking in).
  • 我在返回的路径上进行了一些字符串修剪(因为检查显示新行潜入)。

Modified code:

修改后的代码

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

#2


10  

Everyone seems to have misunderstood the original issue: the path is already setup correctly in Emacs, and the correct path is already passed to the shell started by the compile command! So what gives? Here is the answer:

每个人似乎都误解了原始问题:路径已在Emacs中正确设置,并且正确的路径已经传递给由compile命令启动的shell!什么赋予了什么?这是答案:

In MacOS X, there is a small tool called path_helper(1). It is called by default from /etc/profile, which is executed by Bash on shell startup. When you start a compilation from Emacs, it launches a shell (which by default is Bash on MacOS X), and therefore executes this path_helper tool. And here comes the key point: path_helper rearranges your path, moving the standard directories like /usr/bin in front of your custom added directories, no matter where you originally added them. Try this yourself by opening a shell and first having a look at what PATH is, and then execute /usr/lib/path_helper and have look at the resulting PATH!

在MacOS X中,有一个名为path_helper(1)的小工具。它默认从/ etc / profile调用,由shell启动时由Bash执行。当您从Emacs开始编译时,它会启动一个shell(默认情况下是MacOS X上的Bash),因此执行此path_helper工具。关键点在于:path_helper重新排列路径,在自定义添加的目录前移动标准目录,如/ usr / bin,无论您最初添加它们的位置。通过打开一个shell并首先查看PATH是什么来自己尝试一下,然后执行/ usr / lib / path_helper并查看生成的PATH!

The brute force solution for you might be to simply comment out the call to path_helper in /etc/profile. Note however that then you won't automatically get the paths in /etc/paths.d setup by path_helper, which is the tool's main purpose.

您的强力解决方案可能只是在/ etc / profile中注释掉对path_helper的调用。但是请注意,然后您不会通过path_helper自动获取/etc/paths.d设置中的路径,这是该工具的主要用途。

#3


2  

I don't have a Mac, so I cannot test this directly, but this can all be found in the *info* page Interactive Inferior Shell.

我没有Mac,所以我无法直接测试,但这可以在* info *页面的Interactive Inferior Shell中找到。

When you start a shell in Emacs, the process that gets spawned is the program in the Emacs variable explicit-shell-file-name (and if that is nil, the environment variables ESHELL and SHELL are used).

当您在Emacs中启动shell时,生成的进程是Emacs变量explicit-shell-file-name中的程序(如果为nil,则使用环境变量ESHELL和SHELL)。

It then sends the contents of ~/.emacs_*shellname* (e.g. if your shell is csh, then ~/.emacs_csh would be sent over. Also, the appropriate .rc files for csh program is sourced, so you can update that as well (in my case .cshrc). Additionally, you can wrap customizations in the .rc file with a check for the environment variable INSIDE_EMACS (which which Emacs sets before it runs a shell).

然后它发送〜/ .emacs_ * shellname *的内容(例如,如果你的shell是csh,那么〜/ .emacs_csh将被发送。另外,csh程序的相应.rc文件来源,所以你可以更新为好吧(在我的情况下.cshrc)。此外,您可以在.rc文件中包装自定义项,并检查环境变量INSIDE_EMACS(Emacs在运行shell之前设置的变量)。

You need to update those files to change the path in the shell, not the Emacs variable exec-path. exec-path - which is just a list of directories Emacs uses to find executable programs. The behavior of the executables are not affected by changes to exec-path.

您需要更新这些文件以更改shell中的路径,而不是更改Emacs变量exec-path。 exec-path - 这只是Emacs用于查找可执行程序的目录列表。 exec-path的更改不会影响可执行文件的行为。

#4


2  

I find the environment.plist scheme on Macs pretty ugly, so I use the following snippet, which assumes you want Emacs to use the same PATH that you see in your Terminal.app:

我发现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))))

(This works for me in Emacs 23; haven't tried it in other versions, but I'd expect it to work.)

(这在Emacs 23中适用于我;在其他版本中没有尝试过,但我希望它可以工作。)

#5


0  

try this maybe. replace path string with yours.

试试吧。用你的路径字符串替换。

(add-to-list 'load-path "~/opt/swank-clojure/src/emacs")

(add-to-list'load-path“〜/ opt / swank-clojure / src / emacs”)

#6


0  

As far as I observed, Emacs takes the path variable from the shell it is launched from, so one solution is to change $PATH in the shell before you launch Emacs.

据我观察,Emacs从它启动的shell中获取路径变量,因此一种解决方案是在启动Emacs之前更改shell中的$ PATH。

One other approach I used, which is more flexible, is to use a Makefile and append a "source ~/script_that_set_path" in front of each make commands you have.

我使用的另一种更灵活的方法是使用Makefile并在每个make命令前添加“source~ / script_that_set_path”。

#7


0  

I have tried so many different approaches to this that ended up not using emacs to setup my compilation command environment.

我尝试了很多不同的方法,最终没有使用emacs来设置我的编译命令环境。

What I do now is to create a run_helper.sh file that simply initializes a clean environment and then uses exec $* to execute the command passed as argument to run_helper.sh

我现在做的是创建一个run_helper.sh文件,它只是初始化一个干净的环境,然后使用exec $ *来执行作为参数传递给run_helper.sh的命令

This run_helper.sh is usually project specific, but I keep a template which I use to start with when I create a new project.

这个run_helper.sh通常是项目特定的,但我保留了一个模板,我在创建新项目时使用该模板。

Then I simple run compile from emacs like bash run_helper.sh rspec path/to/tests for example.

然后我简单地从emacs中运行编译,例如bash run_helper.sh rspec path / to / tests。

If I am using this to run ruby tests, my helper initializes RVM to use the proper ruby and gemset. If I am using some other language it may just export required environment variables or perform some other initialization, but this way I can do it in bash script instead of always having to mess with emacs paths and elisp every time I start a new project.

如果我使用它来运行ruby测试,我的助手会初始化RVM以使用正确的ruby和gemset。如果我使用其他语言,它可能只是导出所需的环境变量或执行一些其他初始化,但这样我可以在bash脚本中执行它,而不是每次我开始一个新项目时总是不得不乱用emacs路径和elisp。

Here's an example of a run_helper.sh file

这是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 $*

This also makes my tests run faster because I have lots of stuff in my .zshrc that I don't want to load just to run some tests.

这也使我的测试运行得更快,因为我的.zshrc中有很多东西,我不想加载它来运行一些测试。

#8


0  

It worked for me with two things.

它有两件事对我有用。

First I followed sanityinc advice

首先,我遵循了sanityinc的建议

An improved and modified version of the code snippet is now published as elisp library called exec-path-from-shell; installable packages are available in Marmalade and Melpa

代码片段的改进和修改版本现在作为elisp库发布,名为exec-path-from-shell; Marmalade和Melpa提供可安装的包装

I still had a problem with compile commands. Valko Sipuli is right there was a problem involving path_helper.

我仍然遇到编译命令的问题。 Valko Sipuli是对的,涉及path_helper的问题。

I commented the corresponding line in /etc/profile and it did not help. Problem still there. I don't use bash but zsh. Digging a little I found /etc/zshenv. This file also calls path_helper.

我评论了/ etc / profile中的相应行,但没有帮助。还有问题。我不使用bash而是使用zsh。挖了一点我发现/ etc / zshenv。该文件也调用path_helper。

After commenting the path_helper section in /etc/zshenv my path is finally correct

在评论/ etc / zshenv中的path_helper部分后,我的路径终于正确了

#1


9  

A small modification to the solution by sanityinc (couldn't find a way to enter it in the comments above -- is that just me?)

sanityinc对解决方案的一个小修改(在上面的评论中找不到输入它的方法 - 只有我吗?)

  • I use -l option to the shell to force a login shell (which reads .profile or .bash_profile), rather than an interactive shell (which only reads .bashrc).
  • 我使用-l选项来强制登录shell(读取.profile或.bash_profile),而不是交互式shell(只读取.bashrc)。
  • I do some string trimming on the returned path (as inspection shows a newline sneaking in).
  • 我在返回的路径上进行了一些字符串修剪(因为检查显示新行潜入)。

Modified code:

修改后的代码

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

#2


10  

Everyone seems to have misunderstood the original issue: the path is already setup correctly in Emacs, and the correct path is already passed to the shell started by the compile command! So what gives? Here is the answer:

每个人似乎都误解了原始问题:路径已在Emacs中正确设置,并且正确的路径已经传递给由compile命令启动的shell!什么赋予了什么?这是答案:

In MacOS X, there is a small tool called path_helper(1). It is called by default from /etc/profile, which is executed by Bash on shell startup. When you start a compilation from Emacs, it launches a shell (which by default is Bash on MacOS X), and therefore executes this path_helper tool. And here comes the key point: path_helper rearranges your path, moving the standard directories like /usr/bin in front of your custom added directories, no matter where you originally added them. Try this yourself by opening a shell and first having a look at what PATH is, and then execute /usr/lib/path_helper and have look at the resulting PATH!

在MacOS X中,有一个名为path_helper(1)的小工具。它默认从/ etc / profile调用,由shell启动时由Bash执行。当您从Emacs开始编译时,它会启动一个shell(默认情况下是MacOS X上的Bash),因此执行此path_helper工具。关键点在于:path_helper重新排列路径,在自定义添加的目录前移动标准目录,如/ usr / bin,无论您最初添加它们的位置。通过打开一个shell并首先查看PATH是什么来自己尝试一下,然后执行/ usr / lib / path_helper并查看生成的PATH!

The brute force solution for you might be to simply comment out the call to path_helper in /etc/profile. Note however that then you won't automatically get the paths in /etc/paths.d setup by path_helper, which is the tool's main purpose.

您的强力解决方案可能只是在/ etc / profile中注释掉对path_helper的调用。但是请注意,然后您不会通过path_helper自动获取/etc/paths.d设置中的路径,这是该工具的主要用途。

#3


2  

I don't have a Mac, so I cannot test this directly, but this can all be found in the *info* page Interactive Inferior Shell.

我没有Mac,所以我无法直接测试,但这可以在* info *页面的Interactive Inferior Shell中找到。

When you start a shell in Emacs, the process that gets spawned is the program in the Emacs variable explicit-shell-file-name (and if that is nil, the environment variables ESHELL and SHELL are used).

当您在Emacs中启动shell时,生成的进程是Emacs变量explicit-shell-file-name中的程序(如果为nil,则使用环境变量ESHELL和SHELL)。

It then sends the contents of ~/.emacs_*shellname* (e.g. if your shell is csh, then ~/.emacs_csh would be sent over. Also, the appropriate .rc files for csh program is sourced, so you can update that as well (in my case .cshrc). Additionally, you can wrap customizations in the .rc file with a check for the environment variable INSIDE_EMACS (which which Emacs sets before it runs a shell).

然后它发送〜/ .emacs_ * shellname *的内容(例如,如果你的shell是csh,那么〜/ .emacs_csh将被发送。另外,csh程序的相应.rc文件来源,所以你可以更新为好吧(在我的情况下.cshrc)。此外,您可以在.rc文件中包装自定义项,并检查环境变量INSIDE_EMACS(Emacs在运行shell之前设置的变量)。

You need to update those files to change the path in the shell, not the Emacs variable exec-path. exec-path - which is just a list of directories Emacs uses to find executable programs. The behavior of the executables are not affected by changes to exec-path.

您需要更新这些文件以更改shell中的路径,而不是更改Emacs变量exec-path。 exec-path - 这只是Emacs用于查找可执行程序的目录列表。 exec-path的更改不会影响可执行文件的行为。

#4


2  

I find the environment.plist scheme on Macs pretty ugly, so I use the following snippet, which assumes you want Emacs to use the same PATH that you see in your Terminal.app:

我发现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))))

(This works for me in Emacs 23; haven't tried it in other versions, but I'd expect it to work.)

(这在Emacs 23中适用于我;在其他版本中没有尝试过,但我希望它可以工作。)

#5


0  

try this maybe. replace path string with yours.

试试吧。用你的路径字符串替换。

(add-to-list 'load-path "~/opt/swank-clojure/src/emacs")

(add-to-list'load-path“〜/ opt / swank-clojure / src / emacs”)

#6


0  

As far as I observed, Emacs takes the path variable from the shell it is launched from, so one solution is to change $PATH in the shell before you launch Emacs.

据我观察,Emacs从它启动的shell中获取路径变量,因此一种解决方案是在启动Emacs之前更改shell中的$ PATH。

One other approach I used, which is more flexible, is to use a Makefile and append a "source ~/script_that_set_path" in front of each make commands you have.

我使用的另一种更灵活的方法是使用Makefile并在每个make命令前添加“source~ / script_that_set_path”。

#7


0  

I have tried so many different approaches to this that ended up not using emacs to setup my compilation command environment.

我尝试了很多不同的方法,最终没有使用emacs来设置我的编译命令环境。

What I do now is to create a run_helper.sh file that simply initializes a clean environment and then uses exec $* to execute the command passed as argument to run_helper.sh

我现在做的是创建一个run_helper.sh文件,它只是初始化一个干净的环境,然后使用exec $ *来执行作为参数传递给run_helper.sh的命令

This run_helper.sh is usually project specific, but I keep a template which I use to start with when I create a new project.

这个run_helper.sh通常是项目特定的,但我保留了一个模板,我在创建新项目时使用该模板。

Then I simple run compile from emacs like bash run_helper.sh rspec path/to/tests for example.

然后我简单地从emacs中运行编译,例如bash run_helper.sh rspec path / to / tests。

If I am using this to run ruby tests, my helper initializes RVM to use the proper ruby and gemset. If I am using some other language it may just export required environment variables or perform some other initialization, but this way I can do it in bash script instead of always having to mess with emacs paths and elisp every time I start a new project.

如果我使用它来运行ruby测试,我的助手会初始化RVM以使用正确的ruby和gemset。如果我使用其他语言,它可能只是导出所需的环境变量或执行一些其他初始化,但这样我可以在bash脚本中执行它,而不是每次我开始一个新项目时总是不得不乱用emacs路径和elisp。

Here's an example of a run_helper.sh file

这是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 $*

This also makes my tests run faster because I have lots of stuff in my .zshrc that I don't want to load just to run some tests.

这也使我的测试运行得更快,因为我的.zshrc中有很多东西,我不想加载它来运行一些测试。

#8


0  

It worked for me with two things.

它有两件事对我有用。

First I followed sanityinc advice

首先,我遵循了sanityinc的建议

An improved and modified version of the code snippet is now published as elisp library called exec-path-from-shell; installable packages are available in Marmalade and Melpa

代码片段的改进和修改版本现在作为elisp库发布,名为exec-path-from-shell; Marmalade和Melpa提供可安装的包装

I still had a problem with compile commands. Valko Sipuli is right there was a problem involving path_helper.

我仍然遇到编译命令的问题。 Valko Sipuli是对的,涉及path_helper的问题。

I commented the corresponding line in /etc/profile and it did not help. Problem still there. I don't use bash but zsh. Digging a little I found /etc/zshenv. This file also calls path_helper.

我评论了/ etc / profile中的相应行,但没有帮助。还有问题。我不使用bash而是使用zsh。挖了一点我发现/ etc / zshenv。该文件也调用path_helper。

After commenting the path_helper section in /etc/zshenv my path is finally correct

在评论/ etc / zshenv中的path_helper部分后,我的路径终于正确了