196

看起来launchd.conf不再加载我的环境变量了。有没有其他人注意到这一点?

是否有另一种永久设置环境变量的解决方案?

4

9 回答 9

173

使用以下内容创建一个environment.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>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>
    launchctl setenv PRODUCTS_PATH /Users/mortimer/Projects/my_products
    launchctl setenv ANDROID_NDK_HOME /Applications/android-ndk
    launchctl setenv PATH $PATH:/Applications/gradle/bin
    </string>

  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

您可以在块内添加许多launchctl命令。<string></string>

plist在系统重新启动后激活。您也可以使用launchctl load ~/Library/LaunchAgents/environment.plist它来立即启动它。

[编辑]

同样的解决方案也适用于 El Capitan。

Xcode 7.0+ 默认不评估环境变量。可以使用以下命令启用旧行为:

defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool NO

[编辑]

在某些情况下,这并不完全奏效。如果重新启动计算机并选择“重新登录时重新打开窗口”,重新打开的窗口可能看不到变量(可能它们在代理运行之前打开)。此外,如果您通过 ssh 登录,则不会设置变量(因此您需要在 ~/.bash_profile 中设置它们)。最后,这似乎不适用于 El Capitan 和 Sierra 上的 PATH。这需要通过“launchctl config user path ...”和 /etc/paths.xml 进行设置。

于 2014-10-27T11:05:49.630 回答
65
于 2014-09-18T12:33:37.163 回答
21

可以使用 3 个文件 + 2 个命令在 Mac OS X 10.10 Yosemite 上设置环境变量。

带有环境变量定义的主文件:

$ ls -la /etc/environment 
-r-xr-xr-x  1 root  wheel  369 Oct 21 04:42 /etc/environment
$ cat /etc/environment
#!/bin/sh

set -e

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - start"

launchctl setenv JAVA_HOME      /usr/local/jdk1.7
launchctl setenv MAVEN_HOME     /opt/local/share/java/maven3

if [ -x /usr/libexec/path_helper ]; then
    export PATH=""
    eval `/usr/libexec/path_helper -s`
    launchctl setenv PATH $PATH
fi

osascript -e 'tell app "Dock" to quit'

syslog -s -l warn "Set environment variables with /etc/environment $(whoami) - complete"

为用户应用程序(终端、IDE、...)加载环境变量的服务定义:

$ ls -la /Library/LaunchAgents/environment.user.plist
-rw-------  1 root  wheel  504 Oct 21 04:37 /Library/LaunchAgents/environment.user.plist
$ sudo cat /Library/LaunchAgents/environment.user.plist
<?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>Label</key>
    <string>environment.user</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

root 用户应用程序的相同服务定义:

$ ls -la /Library/LaunchDaemons/environment.plist
-rw-------  1 root  wheel  499 Oct 21 04:38 /Library/LaunchDaemons/environment.plist
$ sudo cat /Library/LaunchDaemons/environment.plist
<?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>Label</key>
    <string>environment</string>
    <key>ProgramArguments</key>
    <array>
            <string>/etc/environment</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment</string>
    </array>
</dict>
</plist>

最后我们应该注册这些服务:

$ launchctl load -w /Library/LaunchAgents/environment.user.plist
$ sudo launchctl load -w /Library/LaunchDaemons/environment.plist

我们得到什么:

  1. 唯一声明系统环境变量的地方:/etc/environment
  2. 修改 /etc/environment 文件后即时自动更新环境变量 - 只需重新启动您的应用程序

问题/问题:

为了在系统重新启动后应用程序正确获取您的环境变量,您将需要:

  • 要么登录两次:登录=>注销=>登录
  • 或手动关闭并重新打开应用程序,其中应采用环境变量
  • 或者不要使用“重新登录时重新打开窗口”功能。

发生这种情况是因为 Apple 拒绝对加载的服务进行显式排序,因此 env 变量与“重新打开队列”的处理并行注册。

但实际上,我每年只重启几次系统(大更新),所以这没什么大不了的。

于 2014-10-21T01:23:02.273 回答
8

引自

Apple Developer Relations 10-Oct-2014 09:12 PM

经过深思熟虑,工程已删除此功能。/etc/launchd.conf出于安全原因,该文件被有意删除。作为一种解决方法,您可以launchctl limit在引导期间尽早以 root 身份运行,也许从LaunchDaemon. (...)

解决方案:

/Library/LaunchDaemons/com.apple.launchd.limit.plist通过 bash-script将代码放入:

#!/bin/bash

echo '<?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>Label</key>
        <string>eicar</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/launchctl</string>
                <string>limit</string>
                <string>core</string>
                <string>unlimited</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceIPC</key>
        <false/>
</dict>
</plist>' | sudo tee /Library/LaunchDaemons/com.apple.launchd.limit.plist
于 2014-10-11T06:20:18.820 回答
4

以下是恢复旧行为的命令:

# create a script that calls launchctl iterating through /etc/launchd.conf
echo '#!/bin/sh

while read line || [[ -n $line ]] ; do launchctl $line ; done < /etc/launchd.conf;
' > /usr/local/bin/launchd.conf.sh

# make it executable
chmod +x /usr/local/bin/launchd.conf.sh

# launch the script at startup
echo '<?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>Label</key>
  <string>launchd.conf</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>/usr/local/bin/launchd.conf.sh</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>
' > /Library/LaunchAgents/launchd.conf.plist

现在您可以指定类似setenv JAVA_HOME /Library/Java/Homein 的命令/etc/launchd.conf

检查 El Capitan。

于 2015-10-06T09:06:43.823 回答
2

什么对我有用(灵感来自 aax' 谢谢):

将此粘贴到/Library/LaunchDaemons/com.apple.launchd.limit.plist然后重新启动:

<?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>Label</key>
  <string>eicar</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>limit</string>
    <string>maxfiles</string>
    <string>16384</string>
    <string>16384</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

如果您需要它一步一步:

  • 启动终端
  • 输入sudo su然后输入密码以 root 身份登录
  • 输入vi /Library/LaunchDaemons/com.apple.launchd.limit.plist
  • 进入 vi 编辑器时,按i键进入插入模式,然后粘贴上面的确切代码内容 ( ⌘+v)。这将强制限制每个进程 16384 个文件,总共 16384 个文件
  • esc保存文件并使用then退出:wq
  • 重新启动系统,并使用命令launchctl limit检查它是否正常工作

我希望这对你有所帮助。

于 2014-10-21T06:41:35.790 回答
2

你可以试试https://github.com/ersiner/osx-env-sync 。它从单一来源处理命令行和 GUI 应用程序,并与最新版本的 OS X (Yosemite) 配合使用。

您可以使用路径替换和其他 shell 技巧,因为您编写的是首先由 bash 获取的常规 bash 脚本。没有限制..(查看osx-env-sync文档,您将了解它是如何实现这一点的。)

我在这里回答了一个类似的问题,您可以在其中找到更多信息。

于 2015-09-07T19:09:28.620 回答
-3

解决方案是将变量添加到/etc/profile. 然后一切都按预期工作!当然,您必须以 root 用户身份使用 sudo nano /etc/profile。如果您以任何其他方式对其进行编辑,即使您将权限更改为 root,系统也会抱怨 /etc/profile 损坏。

于 2014-10-18T12:49:07.497 回答
-5

我通过以下方式在 ~/.bash_profile 中添加了变量。完成后重新启动/注销并登录

export M2_HOME=/Users/robin/softwares/apache-maven-3.2.3
export ANT_HOME=/Users/robin/softwares/apache-ant-1.9.4
launchctl setenv M2_HOME $M2_HOME
launchctl setenv ANT_HOME $ANT_HOME
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/robin/softwares/apache-maven-3.2.3/bin:/Users/robin/softwares/apache-ant-1.9.4/bin
launchctl setenv PATH $PATH

注意:无需重新启动/注销并登录,您可以使用以下方式应用这些更改;

source ~/.bash_profile
于 2015-01-17T23:23:13.723 回答