在OSX Yosemite中,为什么我可以为GUI应用程序设置许多环境变量,却不能设置特定的变量PATH


16

解决了Mavericks发行版中的OSX PATH问题之后,问题又在优胜美地再次出现!!!

因此,我想模仿launch.conf新版Mac OSX 10.10 Yosemite中的旧功能,以便在GUI应用程序(例如Carbon EmacsRStudio)中提供PATH环境变量。我使用了stackoverflow用户ursa的好主意来设置一个shell脚本,该脚本通过配置环境变量launchctl。(请参阅此处的 stackoverflow答案。)这适用于大多数环境变量,但不适用于PATH变量

1.我做了什么?

首先,我将 /etc/environment.rc脚本编写如下:

launchctl setenv PATH /Users/halloleo/bin:/usr/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv JAVA_HOME /usr/local/jdk1.7
launchctl setenv ENVIRONMENT_RC "yes"

然后,我创建了plists用于launchd(下面的附录中的这些脚本和其他提到的脚本的列表)。然后我用

$ sudo launchctrl load ...

然后,我path_helper在Shell初始化文件/etc/配置文件中禁用了该实用程序,以便它不会覆盖environment.rc设置。最后,我重启了机器。

2.有什么作用?

当我启动终端新的环境变量JAVA_HOME,并ENVIRONMENT_RC根据设定environment.rc的,但路径设置为

/ usr / bin:/ bin

为了确保没有任何bash初始化文件妨碍我编写一个小python脚本(也在附录中)来显示当前环境中的变量,因此我直接通过双击Platypus包装器执行此操作。再次设置新变量,而PATH为系统默认值。

那么为什么要设置其他变量,但不能设置PATH变量呢?我该如何统一解决呢?

更新:

这种情况令人非常困惑:bashTerminal或Emacs中的shell(至少)会选择您通过设置的PATH launchctl,但其他GUI应用程序不会这么做。例如,通过Platypus直接调用的上述最小python脚本不会显示您的自定义路径。甚至Emacs本身也不知道正确的PATH:例如,当您发出Emacs命令时,您会注意到这一点M-x ispell-bufferispell如果仅在您的自定义路径上,找不到emacs尝试调用的unix工具。


附录

net.halloleo.environment.plist,启动的配置文件位于/Library/LaunchDaemons/

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

net.halloleo.environment-user.plist,启动的配置文件位于/Library/LaunchAgents/

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment-user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

/etc/profile,修改后的bash启动文件:

# System-wide .profile for sh(1)

# if [ -x /usr/libexec/path_helper ]; then
#   eval `/usr/libexec/path_helper -s`
# fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

show_environ.py,该脚本显示所有环境变量:

import os
print (os.environ)

Answers:


3

优胜美地的PATH可以并且应该在/ etc / paths文件中设置。只需将您的路径添加到此文件的末尾即可:

/usr/bin
/bin
/your/custom/path

原始文章中的 / etc / environment脚本提供了对GUI应用程序中的PATH变量的支持(已通过Emacs测试)。


5
适用于/usr/libexec/path_helper在初始化过程中调用的shell 。根据-的要求,GUI应用程序获取PATH /etc/paths,我专门询问了GUI应用程序。
halloleo 2014年

我已经在原始帖子
ursa 2014年

这是您给出的两个答案
-OP

出现此问题后,@ mark(1)已更新/ etc / environment,现在它确实支持PATH。(2)答案是使用/ etc / paths
ursa 2014年

2
@mark是的,这正是我的观点,问题和问题:通过Finder启动时,如何设置GUI应用程序本身的环境变量PATH?尽管如此,目前尚无真正通用的解决方案……
halloleo 2014年

2

这困扰了我很长时间(嗯,最近几个小时)。最后,我遇到了这个错误报告,似乎准确地描述了我的问题(我不确定该问题与您的问题有关的扩展范围,但是优胜美地/启动似乎与PATH和脚本等结合存在一个错误作为python:

http://www.openradar.me/18945659

解决方案似乎是启动一个shell脚本,然后再启动python。并不是我真正喜欢的东西,但是它就是这样。


感谢您提供的错误报告链接。到目前为止,这是一个真正的错误。我发现它周围还有另一个离合器。我将其张贴在这里。
halloleo 2015年

1

问题在于,launchd会附加另一个PATH变量,而不是替换环境中的那个。大多数程序使用getenv总是返回变量的第一个出现位置,而是用shell遍历所有环境变量并将其作为局部变量导入,从而用最后一个覆盖先前的实例。

显然,这是启动时的错误,传递给程序的环境变量应该是唯一的。


1
很酷的背景答案!我猜这不是在shell中解决它的真实方法,还是在那儿?
halloleo 2015年

@halloleo您可以启动命令,sh -c 'YOUR ORIGINAL COMMAND'该命令将其通过外壳传递,并选择PATH启动中的设置。
StenSoft
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.