【问题标题】:Environment variables in Mac OS XMac OS X 中的环境变量
【发布时间】:2010-10-10 20:48:31
【问题描述】:

更新:下面的链接没有完整的答案。必须在两个地方(一个用于 GUI,一个用于 shell)设置路径或变量是蹩脚的。

不重复Setting environment variables in OS X?


来自 Windows 背景,设置和修改环境变量非常容易(只需转到系统属性 > 高级 > 环境变量),在 Mac OS 10.5 上似乎不是那么简单。大多数参考资料都说我应该更新 /etc/profile 或 ~/.profile。这些等同于系统变量和用户变量吗?例如,我应该在哪里设置我的JAVA_HOME 变量?


编辑:

我希望能够从终端以及像 Eclipse 这样的应用程序访问变量。另外,我希望我不必重新启动/注销即可使其生效。

【问题讨论】:

  • 并且这里不重复链接问题的答案中有一些建议......

标签: macos environment-variables


【解决方案1】:

有几个地方可以设置环境变量。

  • ~/.profile:将其用于要在从终端启动的所有程序中设置的变量(注意,与 Linux 不同,在 Terminal.app 中打开的所有 shell 都是登录 shell)。
  • ~/.bashrc:这是为不是登录 shell 的 shell 调用的。将此用于需要在子 shell 中重新定义的别名和其他内容,而不是用于继承的环境变量。
  • /etc/profile:这是在 ~/.profile 之前加载的,但在其他方面是等效的。当您希望变量应用于机器上所有用户启动的终端程序时使用它(假设他们使用 bash)。
  • ~/.MacOSX/environment.plist:登录时由 loginwindow 读取。它适用于所有应用程序,包括 GUI 应用程序,但 Spotlight 在 10.5(不是 10.6)中启动的应用程序除外。它需要您注销并再次登录才能使更改生效。自 OS X 10.8 起不再支持此文件。
  • 您的用户的launchd 实例:这适用于用户启动的所有程序、GUI 和CLI。您可以随时使用launchctl 中的setenv 命令应用更改。 理论上,您应该可以将setenv 命令放在~/.launchd.conf 中,而launchd 会在用户登录时自动读取它们,但实际上从未实现对这个文件的支持。相反,您可以使用另一种机制在登录时执行脚本,并让该脚本调用launchctl 来设置launchd 环境。
  • /etc/launchd.conf:这是在系统启动和用户登录时由 launchd 读取的。它们会影响系统上的每个进程,因为 launchd 是根进程。要将更改应用到正在运行的 root 启动,您可以将命令通过管道传输到 sudo launchctl

要了解的基本内容是:

  • 环境变量由进程的子进程在派生时继承。
  • 根进程是一个启动实例,每个用户会话也有一个单独的启动实例。
  • launchd 允许您使用launchctl 更改其当前环境变量;从那时起,它派生的所有新进程都会继承更新后的变量。

使用 launchd 设置环境变量的示例:

echo setenv REPLACE_WITH_VAR REPLACE_WITH_VALUE | launchctl

现在,启动使用该变量的 GUI 应用程序,瞧!

要解决~/.launchd.conf 不起作用的事实,您可以将以下脚本放入~/Library/LaunchAgents/local.launchd.conf.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>local.launchd.conf</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>launchctl &lt; ~/.launchd.conf</string>    
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

然后你可以把setenv REPLACE_WITH_VAR REPLACE_WITH_VALUE放在~/.launchd.conf里面,每次登录都会执行。

请注意,当以这种方式将命令列表传送到 launchctl 时,您将无法使用包含空格的值设置环境变量。如果需要,可以调用launchctl,如下:launchctl setenv MYVARIABLE "QUOTE THE STRING"

另外,请注意在登录时运行的其他程序可能在启动代理之前执行,因此可能看不到它设置的环境变量。

【讨论】:

  • 实际上,关于~/.MacOSX/environment.plist,在我的Lion 上它阅读和使用。刚刚测试过了。我实际上比 .launchd.conf 更喜欢它,因为我使用 RCenvironment 首选项窗格来维护它。
  • 无法让 ~/.launchd.conf 在 10.6.8 上工作 - 它似乎没有任何效果。手册页还说此文件当前不受支持。
  • ~/.launchd.conf 似乎也不适用于 10.7.3,当我查看手册页时,它显示 $HOME/.launchd.conf 您的启动配置文件 (目前不支持)
  • 在 10.8 (Mountain Lion) 中,不再支持 ~/.MacOSX/environment.plist。根据 Apple Dev 的说法,必须“将 .app 本身的 Info.plist 更改为包含带有所需环境变量的“LSEnvironment”字典。”有关详细信息,请参阅apple.stackexchange.com/questions/57385/…
  • @LaC 很棒,很全面的帖子;您能否更新它以注意 ~/.launchd.conf 仍然不受支持并且从 OS X 10.8.3 开始不起作用?见man launchd.conf
【解决方案2】:

无需重复。您可以使用 launchctl setenv 设置 launchd(和子进程,即您从 Spotlight 启动的任何内容)使用的环境变量。

例如,如果您想在 .bashrc 或其他任何地方设置好后在 launchd 中镜像当前路径:

PATH=whatever:you:want
launchctl setenv PATH $PATH

环境变量不会在正在运行的应用程序中自动更新。您将需要重新启动应用程序以获取更新的环境变量(尽管您可以在 shell 中设置变量,例如 PATH=whatever:you:want;无需重新启动终端)。

【讨论】:

  • 目前看来是最好的答案,不需要第三方应用!
  • 这似乎不是全局的:以这种方式设置的环境变量对用户来说是本地的。我们仍然没有设置环境变量的全局机制。
  • @Andrew 你是什么意思,本地用户?我希望随后从 launchd 开始的所有进程都会受到影响。
  • @Andrew OK,root 有自己的 launchd - ps aux | grep launchd 会显示这个。还要检查man sudo,其中记录了sudo(默认情况下)故意重置环境-如果您sudo -E它将保留环境(包括您使用launchctl setenv设置的变量)。顺便说一句,你有这方面的实际应用吗?如果是这样,这种方法对你有用吗?
  • launchctl config system path $PATH 将负责 root 启动。我相信launchctl config user path $PATH 将是为用户启动设置持久路径的首选方式。 (与setenv 相比)。
【解决方案3】:

我认为 OP 正在寻找的是一个简单的、类似 Windows 的解决方案。

给你:

https://www.macupdate.com/app/mac/14617/rcenvironment

【讨论】:

  • 哇,这看起来很酷。还没试过,但看起来正是我需要的描述。
  • 顺便说一句,自从我发布后,原始链接似乎已经断开(Apple 怎么了?301 很贵?)。您可以改用此链接:macupdate.com/app/mac/14617/rcenvironment
  • 这真的很老了。查看另一个提到 osx-env-sync 的答案,了解即使在 OS X 10.10 (Yosemite) 及更高版本中也可以使用的现代解决方案。
  • 请在您的答案中总结链接中的信息。正如我们已经看到的,链接断开的原因有很多。
【解决方案4】:

您可以在 linux 上阅读,这与 Mac OS X 非常接近。或者你可以阅读 BSD Unix,它更接近一点。在大多数情况下,Linux 和 BSD 之间的差异并不大。

/etc/profile 是系统环境变量。

~/.profile 是用户特定的环境变量。

“我应该在哪里设置我的 JAVA_HOME 变量?”

  • 您有多个用户吗?他们在乎吗?你会通过更改/etc/profile 来搞乱其他用户吗?

一般来说,即使我是唯一的用户,我也不喜欢搞乱系统范围的设置。我更喜欢编辑本地设置。

【讨论】:

    【解决方案5】:

    对于 GUI 应用程序,您必须创建和编辑 ~/.MacOSX/environment.plist。更多详情here。您需要注销才能使这些生效。我不确定它们是否也会影响从终端启动的应用程序,但我认为它们会。

    对于从终端启动的应用,您还可以编辑 ~/.profile 文件。

    【讨论】:

    • 是的,终端将继承变量,从终端启动的任何东西也是如此。您可以使用RCenvironment 首选项窗格来维护变量。
    • 此解决方案不再适用于 Mac OS X v10.7 的某些修订版。它不适用于任何 Mac OS X v10.8 或更高版本。相反,请参阅:stackoverflow.com/a/4567308/543738
    【解决方案6】:

    使用 osx-env-sync 从单一来源同步命令行和 GUI 应用程序的 OS X 环境变量。

    我还发布了一个相关问题here的答案。

    【讨论】:

    • 这太棒了。建议:将launchctl unload / launctl load "refresh now" 的东西放到一个脚本中。我称它为 osx-env-sync-now.sh。我修改我的 .bash_profile 并运行“立即刷新”小脚本并继续。我认为这里有安全隐患,所以我认为应该做一些限制。他们在 OS X 中关闭此功能肯定是有原因的。
    • @WarrenP 完成!检查回购。
    • 优秀。这为我解决了很多痛苦。对于使用 SCALA 开发的任何人来说,这确实有用的一种情况。否则,为命令行 scala 和 GUI scala(例如在 netbeans 中)设置 SCALA_HOME 真的很痛苦。
    【解决方案7】:

    只需在终端中通过nano 打开~/.profile 文件,然后在其中输入:

    export PATH=whatever/you/want:$PATH
    

    保存此文件(cmd+X 和 Y)。 之后,请再次注销/登录,或者在终端中打开一个新选项卡并尝试使用您的新变量。

    请不要忘记在任何/你/想要的之后添加“:$PATH”,否则你将删除 PATH 变量中的所有路径,这些路径在此之前就存在。

    【讨论】:

    • 这仅适用于 bash 命令环境。 GUI 应用程序看不到您在此处设置的变量。
    【解决方案8】:

    我编写了一个工具来轻松管理 macOS 应用程序的环境变量。

    https://github.com/yuezk/macenv

    可以用~/.macenv set设置环境变量,例如:

    ~/.macenv set JAVA_HOME /path/to/java/home
    

    在后台,它调用launchctl setenv设置环境变量,同时将环境变量保存到~/.launchd.conf,并注册一个自动启动服务以在操作系统重启时加载环境变量。

    【讨论】:

      【解决方案9】:

      如果您想在 macOS 上永久更改环境变量,请将它们设置为 /etc/paths注意,这个文件默认是只读的,所以你必须chmod来获得写权限。

      【讨论】:

      • 这对我不起作用。我在该文件中有/usr/bin/local,即使没有修改文件,默认情况下也是如此,但我的GUI应用程序只能看到/usr/bin:/bin:/usr/sbin:/sbin。我重启了很多次。
      • @m_gol 运行cat /etc/paths/会得到什么?
      • /usr/local/bin、/usr/bin、/bin、/usr/sbin、/sbin,在单独的行中。然而,SourceTree 可以看到除第一个之外的所有这些。
      • 您可能需要编辑为“如果您想更改 macOS 中的默认 路径”。这与更普遍的环境变量问题没有任何关系。
      【解决方案10】:

      对于 2020 Mac OS X Catalina 用户:

      忘记其他无用的答案,这里只需要两个步骤:

      1. 使用命名约定创建一个文件:priority-appname。然后将要添加的路径复制粘贴到PATH

        例如80-vscode 在我的情况下,内容为 /Applications/Visual Studio Code.app/Contents/Resources/app/bin/

      2. 将该文件移至/etc/paths.d/。不要忘记在终端中打开一个新选项卡(新会话)并输入echo $PATH 以检查您的路径是否已添加!

      注意:此方法仅追加您到PATH 的路径。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-23
        • 2013-05-04
        • 2011-08-30
        • 2017-07-08
        • 2013-11-27
        • 2011-11-22
        • 2014-04-25
        相关资源
        最近更新 更多