通过launchd.conf设置环境变量不再适用于OS X Yosemite/El Capitan/macOS Sierra/Mojave?

看起来launchd.conf不再加载我的环境变量了。 有人注意到吗?< / p >

是否有其他永久设置环境变量的解决方案?

132921 次浏览

[原来的答案]:你仍然可以使用launchctl setenv variablename value来设置一个变量,以便被所有应用程序(除了通过终端启动的图形应用程序外,还可以通过Dock或Spotlight启动图形应用程序)拾取。

显然,您不会希望每次登录都这样做。

[编辑]:为了避免这种情况,启动AppleScript Editor,输入如下命令:

do shell script "launchctl setenv variablename value"

(如果要设置多个变量,请使用多行)

现在将(+s)保存为文件格式:。最后打开System Settings用户,组登录物品并添加新应用程序。

[原来的答案]:要在这个地方工作,你希望在一个简短的shell脚本中定义的所有变量,然后看一下这个之前关于如何在MacOS登录上运行脚本的回答。这样,脚本将在用户登录时被调用。

[编辑]:两种解决方案都不是完美的,因为变量只会为具体的用户设置,但我希望/猜测这可能是你所需要的。

如果你确实有多个用户,你可以手动为每个用户设置登录物品,或者在他们的每个本地图书馆/ LaunchAgents目录中放置一个com.user.loginscript.plist的副本,指向同一个shell脚本。

当然,这些变通方法都没有/etc/launchd.conf那么方便。

[进一步的编辑]:下面的一个用户提到这对他不起作用。然而,我在约塞米蒂的多台机器上测试过,它确实对我有用。如果遇到问题,请记住需要重新启动应用程序才能生效。此外,如果你通过~ / . profile~ / . bash_profile在终端中设置变量,它们将覆盖通过launchctl setenv应用程序从shell启动设置的内容。

引用从

苹果开发者关系 10-Oct-2014 09:12 PM

经过深思熟虑,工程师已经删除了这个功能。 出于安全原因,文件/etc/launchd.conf被故意删除。 作为一种变通方法,你可以在引导早期以根目录的身份运行launchctl limit,也许是从LaunchDaemon。(…)< / p >

解决方案:

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

#!/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
解决方案是将你的变量添加到/etc/profile。然后一切都按照预期工作! 当然,你必须以root用户使用sudo nano /etc/profile如果你用其他方式编辑它,系统会报错说/etc/profile已经损坏,即使你把权限改成了root。< / p >

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

包含环境变量定义的主文件:

$ 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>

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

$ 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文件后立即自动更新环境变量-只需重新启动应用程序

问题/问题:

为了让你的env变量被应用程序系统重启后正确地获取,你将需要:

  • 任意两次登录:login => logout => login
  • 或关闭&手动重新打开应该使用env变量的应用程序
  • 或者不要使用“登录时重新打开窗口”功能。

这是由于苹果拒绝显式地对加载的服务进行排序,所以env变量与“重新打开队列”的处理并行注册。

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

对我有用的(从aax的感谢中得到启发):

将此粘贴到/图书馆/ 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苏,然后输入密码以root用户登录
  • 类型vi /图书馆/ LaunchDaemons / com.apple.launchd.limit.plist
  • 进入vi编辑器时,按下键进入插入模式,然后粘贴上面的确切代码内容(⌘+v)。这将强制每个进程限制为16384个文件,总共为16384个文件
  • 保存文件并使用esc退出,然后使用:wq退出
  • 重新启动系统,并使用命令launchctl限制检查系统是否正常工作

我希望这对你有所帮助。

~/Library/LaunchAgents/中创建一个包含以下内容的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>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>

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

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

(编辑)

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

Xcode 7.0+默认情况下不计算环境变量。旧的行为可以用这个命令启用:

defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool否 < /代码> < / p >

(编辑)

在一些情况下,这种方法是行不通的。如果计算机重新启动并且选择了“重新登录时重新打开窗口”,重新打开的窗口可能看不到变量(可能是在代理运行之前打开的)。此外,如果您通过ssh登录,则不会设置变量(因此需要在~/.bash_profile中设置它们)。最后,这似乎不适用于PATH在El Capitan和Sierra的项目。这需要通过'launchctl config用户路径…'和在/etc/paths.

我将变量添加到~/。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

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

您可以使用路径替换和其他shell技巧,因为您所编写的是bash首先提供的常规bash脚本。没有限制。(检查osx-env-sync文档,你会明白它是如何实现这一点的。)

我回答了一个类似的问题在这里,你会发现更多。

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

# 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

现在你可以在/etc/launchd.conf中指定像setenv JAVA_HOME /Library/Java/Home这样的命令。

查过酋长号了。