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

Tos*_*osh 185 environment-variables osx-yosemite osx-elcapitan

它看起来好像launchd.conf不再加载我的环境变量了.还有其他人注意到了吗?

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

Mor*_*oro 152

使用此内容创建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>
Run Code Online (Sandbox Code Playgroud)

您可以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设置.

  • 无需重启!您可以执行"launchctl start environment.plist"并重新启动获取新环境变量所需的应用程序;) (19认同)
  • 弄清楚:要在不重启的情况下工作,它应该是"launchctl _load_ environment.plist",而不是_start_ (6认同)
  • `sudo launchctl config user path $PATH` 适用于 Mojave (5认同)
  • 这不再起作用,请查看[EnvPane](https://github.com/hschmidt/EnvPane) (3认同)
  • 我不得不重新开始工作 (2认同)
  • 没错.没有什么比在整个互联网上出现9次的模糊配置设置(google`UseSanitizedBuildSystemEnvironment`). (2认同)
  • 也适用于塞拉利昂 (2认同)

rua*_*rio 63

[ 原始答案 ]:您仍然可以使用launchctl setenv variablename value设置变量,以便所有应用程序(通过Dock或Spotlight启动的图形应用程序,以及通过终端启动的应用程序)选择该变量.

显然,每次登录时都不会想要这样做.

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

do shell script "launchctl setenv variablename value"
Run Code Online (Sandbox Code Playgroud)

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

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

[ 原始答案 ]:要在这个地方解决您希望在短shell脚本中定义的所有变量,然后查看此前有关如何在MacOS登录上运行脚本的答案.这样,当用户登录时将调用脚本.

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

如果您有多个用户,则可以手动为每个用户设置一个登录项,或者在每个本地Library/LaunchAgents目录中放置一个com.user.loginscript.plist的副本,指向相同的shell脚本.

当然,这些变通办法都不像/etc/launchd.conf那样方便.

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

  • 据我所知,这种技术的一个缺点是,不会为登录时启动的任何其他应用程序设置变量.因此,例如,如果您打开终端,该变量将被设置,但如果您注销并重新打开,让终端自动重启,该变量将被取消... (5认同)
  • 使用上述方法之一并重新启动笔记本电脑后 - 确保明确重新打开应用程序(例如iTerm,终端,Eclipse,IDEA或您正在使用的任何内容).如果没有显式重新启动它们,并且如果在重新启动OSx时复选框被选中"重新登录时重新启动窗口"(这是默认设置) - 那些程序将不会读取新的环境变量. (3认同)
  • 这将是一般的,但是Yosemite(至少10.10.0和10.10.1)中存在一个错误,其中设置$ PATH不会这样.Apple知道这个bug.目前(截至10.10.1)没有已知的方法为GUI应用程序设置系统范围的$ PATH. (2认同)

urs*_*rsa 21

可以在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"
Run Code Online (Sandbox Code Playgroud)

用于为用户应用程序(终端,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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

$ launchctl load -w /Library/LaunchAgents/environment.user.plist
$ sudo launchctl load -w /Library/LaunchDaemons/environment.plist
Run Code Online (Sandbox Code Playgroud)

我们得到了什么:

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

问题/问题:

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

  • 登录两次:login => logout => login
  • 或者手动关闭并重新打开应用程序,其中应该采用env变量
  • 或者不要使用"重新登录时重新打开窗口"功能.

这是因为Apple拒绝加载服务的显式排序,因此env变量与"重新打开队列"的处理并行注册.

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

  • 应使用/ etc/paths文件设置PATH.只需将自定义路径添加到此文件的末尾即可. (4认同)

aax*_*aax 6

引自

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

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

解:

将代码放入/Library/LaunchDaemons/com.apple.launchd.limit.plistbash-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
Run Code Online (Sandbox Code Playgroud)

  • xml未完全复制.doctype行应为`<!DOCTYPE plist PUBLIC" - // Apple // DTD PLIST 1.0 // EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">` (5认同)
  • @aax该plist的哪一部分实际上设置了一个环境变量? (5认同)

yan*_*nko 5

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

# 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
Run Code Online (Sandbox Code Playgroud)

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

检查了 El Capitan。