ChatGPT解决这个技术问题 Extra ChatGPT

在 OS X 上设置环境变量

在 OS X 中修改 PATH 等环境变量的正确方法是什么?

我在谷歌上看了一点,发现三个不同的文件要编辑:

/etc/路径

~/.profile

~/.tcshrc

我什至没有这些文件,而且我很确定 .tcshrc 是错误的,因为 OS X 现在使用 bash。这些变量,尤其是 PATH,在哪里定义?

我正在运行 OS X v10.5(豹)。

env "switch.1.disabled=true" open -n /Applications/Eclipse.app/ 使用新设置的系统环境启动 GUI 应用程序。
.tcshrc 显然只有在您使用 Tcsh 时才有用。如果你愿意,欢迎来到 21 世纪!听说现在有与 Bourne 兼容的免费开源 shell,您会感到惊讶。

F
Frankenmint

布鲁诺是正确的。我进行了广泛的研究,如果您想设置在所有 GUI 应用程序中都可用的变量,您唯一的选择是 /etc/launchd.conf

请注意environment.plist does not work for applications launched via Spotlight. This is documented by Steve Sexton here

打开终端提示输入 sudo vi /etc/launchd.conf (注意:此文件可能尚不存在)将如下内容放入文件中 # 在此处设置环境变量,以便它们对所有应用程序全局可用 #(和终端),包括那些通过 Spotlight 推出的。 # # 编辑此文件后,从终端运行以下命令以全局更新 # 环境变量,而无需重新启动。 # 注意:您仍然需要重新启动相关应用程序(包括 # 终端)才能获取更改! # grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl # # 见 http://www.digitaledgesw.com/node/31 # 和 http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x/ # # 注意你必须硬编码下面的路径,不要使用环境变量。 # 您还需要将多个值括在引号中,请参见下面的 MAVEN_OPTS 示例。 # setenv JAVA_VERSION 1.6 setenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home setenv GROOVY_HOME /Applications/Dev/groovy setenv GRAILS_HOME /Applications/Dev/grails setenv NEXUS_HOME /Applications/Dev/nexus/nexus-webapp setenv JRUBY_HOME /Applications/Dev/jruby setenv ANT_HOME /Applications/Dev/apache-ant setenv ANT_OPTS -Xmx512M setenv MAVEN_OPTS "-Xmx1024M -XX:MaxPermSize=512m" setenv M2_HOME /Applications/Dev/apache-maven setenv JMETER_HOME /Applications/Dev /jakarta-jmeter 在 vi 中保存您的更改并重新启动您的 Mac。或者使用上面代码注释中显示的 grep/xargs 命令。通过打开终端窗口并键入 export 来证明您的变量正在工作,您应该会看到新变量。这些也将在 IntelliJ IDEA 和您通过 Spotlight 启动的其他 GUI 应用程序中可用。


我是说接受的答案(environment.plist)对我来说并不成功。我已经在四台机器上成功地在 10.5 和 10.6 上使用了 launchd.conf 方法。
有没有办法在不重新启动系统的情况下做到这一点?
上述限制适用于 MacOS X 10.5。然而,MacOS X 10.6 不再有这个限制,并且在 environment.plist 中设置值即使对于通过聚光灯启动的应用程序也可以正常工作。所以选择的答案对于雪豹来说是正确的;-)
设置 launchd.conf 是一种方法,但需要重新启动(重新启动 launchd)。如果您想避免重新启动,请参阅我的回答 stackoverflow.com/questions/135688/…
所提出的 launchd 方法存在几个问题。大多数特定于 PATH 环境变量,但提问者确实特别提到了 PATH 。 1) launchd.conf 中的项目不会在交互式 shell(例如 ssh)中应用到系统中。 2) 将“setenv PATH /testdir”行附加到 Terminal.app 中的 PATH 中,但会清除 OS X 应用程序环境中的所有其他 PATH 项。 3)在 /etc/launchd.conf 中执行“setenv PATH ${PATH}:/testdir”不能正确扩展现有的 $PATH 4)launchd.conf 适用于所有用户,而不仅仅是一个用户。并不是说我有更好的解决方案。
M
Matt Curtis

不要指望 ~/.launchd.conf 工作

launchctl 的手册页说它从来没有工作过:

已弃用和删除的功能 launchctl 不再具有交互模式,也不接受来自标准输入的命令。 /etc/launchd.conf 文件不再用于在早期引导期间运行子命令;出于安全考虑,此功能已被删除。虽然记录在设置用户会话之前会咨询 $HOME/.launchd.conf,但从未实现此功能。

如何为 Spotlight 启动的新进程设置环境(无需重启)

您可以使用 launchctl setenv 设置 launchd 使用的环境(以及,通过扩展,从 Spotlight 启动的任何内容)。例如设置路径:

launchctl setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

或者,如果您想在 .bashrc 或类似中设置路径,则将其镜像到 launchd:

PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv PATH $PATH

无需重新启动,但如果您希望应用程序恢复更改的环境,则需要重新启动应用程序。

这包括任何已经在 Terminal.app 下运行的 shell,但如果您在那里,您可以更直接地设置环境,例如使用 export PATH=/opt/local/bin:/opt/local/sbin:$PATH 来设置 bash 或 zsh。

重启后如何保留更改

新方法(自 10.10 Yosemite 起)

使用 launchctl config user path /bin:/usr/bin:/mystuff。有关详细信息,请参阅 man launchctl

以前的方法

该答案顶部的 launchctl 手册页引用说,出于安全原因,此处描述的功能(在启动时读取 /etc/launchd.conf)已被删除,因此 ymmv.

重启后保留更改,您可以从 /etc/launchd.conf 设置环境变量,如下所示:

setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

launchd.conf 会在您重新启动时自动执行。

如果您希望这些更改现在生效,您应该使用此命令重新处理 launchd.conf(感谢@mklement 的提示!)

egrep -v '^\s*#' /etc/launchd.conf | launchctl

您可以使用命令 man launchctl 了解有关 launchctl 以及它如何加载 launchd.conf 的更多信息。


很不错的一个!使用 environment.plist 的优点似乎是 OS X 尊重该文件的内容,而无需先启动终端。无论如何,我认为您的回答主要集中在避免重新启动的必要性上,所以谢谢。
@kapuzineralex 是的,它避免了重新启动,它还改变了从 Spotlight 启动的程序的环境,而 environment.plist 没有这样做。
以这种方式设置环境只对我有用,直到我重新启动。重新启动mac后,环境变量没有持续。马修的回答对我来说非常有效。
@Shamal:我为您的评论+1,但请记住马修的回答需要重新启动,而我指出了无需重新启动即可更改它的正确方法。如果你想要两者,我建议你把你的路径设置放在launchd.conf中(这样它们在重新启动后仍然存在),然后使用类似“source /etc/launchctl.conf;launchctl setenv PATH $PATH”的脚本,所以当您不想重新启动时,您也可以“刷新”。
@MattCurtis 您能否直接编辑您的答案,以明确说明虽然不需要重新启动,但重新启动后更改实际上会丢失?此外,在重新启动之前在 etc/launchd.conf 中应用更改的正确方法是使用 @MatthewMcCullough 的回答中的方法:egrep "^setenv\ " /etc/launchd.conf | xargs -t -L 1 launchctl
P
Peter Mortensen

直到并包括 OS X v10.7 (Lion),您可以将它们设置为:

~/.MacOSX/environment.plist

看:

https://developer.apple.com/legacy/library/qa/qa1067/_index.html

https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/EnvironmentVars.html

对于终端中的 PATH,您应该可以在 .bash_profile.profile 中设置(尽管您可能必须创建它)

适用于 OS X v10.8(Mountain Lion)及其他地区 you need to use launchd and launchctl


仅当您确实希望它们被图形应用程序使用时。由于这些通常不使用环境变量,因此它不是设置它们的好地方。
有一些非常好的使用环境变量的图形应用程序示例。例如,IntelliJ 喜欢能够看到 M2_HOME 以了解 Maven 所在的位置。要让它查看变量,您需要在 /etc/launchd.conf 而不是 environment.plist 中设置它。
供参考:在 OS X 10.5 中使用 preferences.plist 不太理想,因为当时没有为通过聚光灯启动的应用程序读取 preferences.plist,请参阅 Louis 对 Matthew 的回答和 email.esm.psu.edu/pipermail/macosx-emacs/2010-May/002113.html 的评论。对于 OS X 10.6,environment.plist 可以正常工作。
这不再适用于 OSX 10.8 apple.stackexchange.com/questions/57385/…
@tim_yates 您能否将答案的第一行编辑为“Up to and include Lion (10.*7*)”,因为这是正确的?我试图对原始的、模棱两可的“Up to Mountain Lion”进行编辑,但评论家把它搞砸了。
S
Stepan Vavra

来自单一来源的命令行和 GUI 应用程序的解决方案(适用于 Mac OS X v10.10 (Yosemite) 和 Mac OS X v10.11 (El Capitan))

假设您的 ~/.bash_profile 中有环境变量定义,如以下代码段所示:

export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
export GOPATH="$HOME/go"
export PATH="$PATH:/usr/local/opt/go/libexec/bin:$GOPATH/bin"
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"

我们需要一个启动代理,它将在每次登录时运行,并且随时按需运行,它将这些变量加载到用户会话中。我们还需要一个 shell 脚本来解析这些定义并构建必要的命令以由代理执行。

~/Library/LaunchAgents/ 目录中创建一个后缀为 plist 的文件(例如名为 osx-env-sync.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>osx-env-sync</string>
  <key>ProgramArguments</key>
  <array>
    <string>bash</string>
    <string>-l</string>
    <string>-c</string>
    <string>
      $HOME/.osx-env-sync.sh
    </string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

-l 参数在这里很关键;必须使用 login shell 执行 shell 脚本,以便在执行此脚本之前首先获取 ~/.bash_profile

现在,shell 脚本。使用以下内容在 ~/.osx-env-sync.sh 创建它:

grep export $HOME/.bash_profile | while IFS=' =' read ignoreexport envvar ignorevalue; do
  launchctl setenv "${envvar}" "${!envvar}"
done

确保 shell 脚本是可执行的:

chmod +x ~/.osx-env-sync.sh

现在,为当前会话加载启动代理:

launchctl load ~/Library/LaunchAgents/osx-env-sync.plist

(重新)启动一个 GUI 应用程序并验证它是否可以读取环境变量。

设置是持久的。它将在重新启动和重新登录后继续存在。

在初始设置(您刚刚完成)之后,如果您想再次将 ~/.bash_profile 中的任何更改反映到整个环境,重新运行 launchctl load ... 命令将不会执行您想要的操作;相反,您会收到如下警告:

<$HOME>/Library/LaunchAgents/osx-env-sync.plist: Operation already in progress

为了在不经过注销/登录过程的情况下重新加载您的环境变量,请执行以下操作:

launchctl unload ~/Library/LaunchAgents/osx-env-sync.plist
launchctl load ~/Library/LaunchAgents/osx-env-sync.plist

最后确保您重新启动已经运行的应用程序(包括 Terminal.app),以使它们知道这些更改。

我还将此处的代码和解释推送到 GitHub 项目:osx-env-sync

我希望这将是最终的解决方案,至少对于最新版本的 OS X(Yosemite 和 El Capitan)而言。


效果很好。有点担心这个如果流行起来会不会是一个安全漏洞
这个解决方案是我唯一可以正常工作的解决方案。很棒的解决方案。我不明白为什么这在mac上应该这么难......
不幸的是,这在 El Capitan 上不起作用。您来自 github.com/ersiner/osx-env-sync/issues/1#issuecomment-169803508 的评论很好地解释了这个问题。
因此,此解决方案不起作用,/etc/launchd.conf 无效,Node.js 将其二进制文件安装到 /usr/local/bin 并且此路径不在 GUI 应用程序的 PATH 中。因此,使用 Node 的 Git 钩子在 El Capitan 中根本无法在像 SourceTree 这样的 GUI Git 应用程序中工作。这很糟糕。
问题仅与 PATH 变量有关。我希望我们能尽快找到解决办法。
P
Peter Mortensen

执行: vim ~/.bash_profile 该文件可能不存在(如果不存在,您可以创建它)。输入这个并保存文件:export PATH=$PATH:YOUR_PATH_HERE Run source ~/.bash_profile


+1 export 是我要建议的,因为 BASH 不支持 setenv
现在工作。整个事情看起来比我想象的要复杂得多。稍后将不得不为所有这些投入更多时间。谢谢。
d
dcow

在 OS X 中处理环境变量时基本上有两个问题需要解决。第一个是从 Spotlight(Mac 菜单/状态栏右侧的放大镜图标)调用程序时,第二个是从 Dock 调用程序时.从终端应用程序/实用程序调用程序很简单,因为它从标准 shell 位置(~/.profile~/.bash_profile~/.bashrc 等)读取环境。

从 Dock 调用程序时,请使用 ~/.MacOSX/environment.plist,其中 <dict> 元素包含一系列 <key>KEY</key><string>theValue</string> 元素。

从 Spotlight 调用程序时,请确保已使用您需要的所有键/值设置设置了 launchd。

为了同时解决这两个问题,我在我的用户帐户上使用了登录项(通过系统偏好设置工具设置)。登录项是一个调用 Emacs lisp 函数的 bash 脚本,当然可以使用他们最喜欢的脚本工具来完成同样的事情。这种方法有一个额外的好处,它可以在任何时候工作并且不需要重新启动,即可以编辑 ~/.profile,在某些 shell 中运行登录项,并且可以从 Dock 或 Spotlight 看到新调用的程序的更改.

细节:

登录项:~/bin/macosx-startup

#!/bin/bash
bash -l -c "/Applications/Emacs.app/Contents/MacOS/Emacs --batch -l ~/lib/emacs/elisp/macosx/environment-support.el -f generate-environment"

Emacs lisp 函数:~/lib/emacs/elisp/macosx/envionment-support.el

;;; Provide support for the environment on Mac OS X

(defun generate-environment ()
  "Dump the current environment into the ~/.MacOSX/environment.plist file."
  ;; The system environment is found in the global variable:
  ;; 'initial-environment' as a list of "KEY=VALUE" pairs.
  (let ((list initial-environment)
        pair start command key value)
    ;; clear out the current environment settings
    (find-file "~/.MacOSX/environment.plist")
    (goto-char (point-min))
    (setq start (search-forward "<dict>\n"))
    (search-forward "</dict>")
    (beginning-of-line)
    (delete-region start (point))
    (while list
      (setq pair (split-string (car list) "=")
            list (cdr list))
      (setq key (nth 0 pair)
            value (nth 1 pair))
      (insert "  <key>" key "</key>\n")
      (insert "  <string>" value "</string>\n")

      ;; Enable this variable in launchd
      (setq command (format "launchctl setenv %s \"%s\"" key value))
      (shell-command command))
    ;; Save the buffer.
    (save-buffer)))

注意:此解决方案是我添加之前的解决方案的混合体,特别是由 Matt Curtis 提供的解决方案,但我故意尝试保持我的 ~/.bash_profile 内容平台独立并将 launchd 环境的设置(仅限 Mac设施)到一个单独的脚本。


哇。我并不是说这行不通,但是……我只是对在 OS X 上获得一致环境所需的复杂性感到震惊。
这是我在 10.9 中看到的所有解决方案中效果最好的。唯一的缺陷是,由于登录项以不确定的顺序运行,如果 Emacs(例如)在登录时启动(例如,因为它在注销时打开),除非您重新启动它,否则它不一定具有环境变量,因为它是在您的脚本启动之前启动的。
P
Peter Mortensen

另一种免费的开源 Mac OS X v10.8 (Mountain Lion) Preference pane/environment.plist 解决方案是 EnvPane

EnvPane 的 source codeGitHub 上可用。 EnvPane 看起来具有与 RCEnvironment 类似的功能,但是,它似乎可以立即更新其存储的变量,即 无需重新启动或登录,这是受欢迎的。

正如开发商所说:

EnvPane 是 Mac OS X 10.8 (Mountain Lion) 的首选项窗格,可让您在图形和终端会话中为所有程序设置环境变量。它不仅恢复了对 Mountain Lion 中 ~/.MacOSX/environment.plist 的支持,它还立即发布您对环境的更改,而无需注销并重新登录。 EnvPane 包括(并自动安装)一个启动代理,它在 1) 登录后及早 2) 每当 ~/.MacOSX/environment.plist 更改时运行。代理读取 ~/.MacOSX/environment.plist 并通过 launchctl setenv 和 launchctl unsetenv 使用的相同 API 将该文件中的环境变量导出到当前用户的 launchd 实例。

免责声明:我与开发人员或他/她的项目没有任何关系。

PS我喜欢这个名字(听起来像'Ends Pain')。


EnvPane 目前无法设置 PATH。有关更多详细信息,请参阅我的错误报告:github.com/hschmidt/EnvPane/issues/5
我♥️这件事..唯一的缺点..我认为任何解决方案都会成为受害者..是 - 必须重新启动一个进程 - 继承新的“环境”。汪汪汪汪。
@sorin:你能在 GitHub 网站上打开一个问题,描述你遇到的问题吗? EnvPane 在 10.10 上为我工作。免责声明:我是 EnvPane 的作者。
P
Peter Mortensen

在 Mountain Lion 上,所有的 /etc/paths/etc/launchd.conf 编辑都没有任何效果!

苹果的开发者论坛说:

“将 .app 本身的 Info.plist 更改为包含带有所需环境变量的“LSEnvironment”字典。不再支持 ~/.MacOSX/environment.plist。”

所以我直接编辑了应用程序的 Info.plist(右键单击“AppName.app”(在本例中为 SourceTree),然后单击“Show package contents”)。

https://i.stack.imgur.com/Z6ZHP.png

我添加了一个新的密钥/字典对,称为:

<key>LSEnvironment</key>
<dict>
     <key>PATH</key>
     <string>/Users/flori/.rvm/gems/ruby-1.9.3-p362/bin:/Users/flori/.rvm/gems/ruby-1.9.3-p362@global/bin:/Users/flori/.rvm/rubies/ruby-1.9.3-p326/bin:/Users/flori/.rvm/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:</string>
</dict>

(见:LaunchServicesKeys Documentation at Apple

https://i.stack.imgur.com/oiwcE.png

现在应用程序(在我的例子中是 Sourcetree)使用给定的路径并使用 Git 1.9.3 :-)

PS:当然,您必须根据您的特定路径需求调整路径条目。


该解决方案符合对系统干扰最小的标准。谢谢。
@John Vance +1 完全同意,系统范围的更改总是有风险的,正如 Jason T. Miller 在他的回答中清楚地解释的那样
在 El Capitan 对我没有影响。 :(
在 High Sierra 10.13 上,如果我修改应用程序的 Info.plist 文件,则应用程序无法加载:LSOpenURLsWithRole() failed with error -10810 for the file /Applications/Slack.app.
M
Max Leske

更新 (2017-08-04)

从(至少)macOS 10.12.6 (Sierra) 开始,此方法似乎已停止适用于 Apache httpd(对于 launchctl configsystemuser 选项)。其他程序似乎没有受到影响。可以想象这是httpd的一个bug。

原始答案

这涉及 OS X 10.10+(10.11+ 特别是由于 /usr/bin 不再可写的无根模式)。

我在多个地方读到使用 launchctl setenv PATH <new path> 设置 PATH 变量由于 OS X 中的错误而不起作用(从个人经验来看,这似乎是正确的)。我发现还有另一种方法可以为 不是从 shell 启动的应用程序设置 PATH

sudo launchctl config user path <new path>

该选项记录在 launchctl 手册页中:

配置系统 |用户参数值 设置launchd(8) 域的持久配置信息。只能配置系统域和用户域。持久存储的位置是一个实现细节,只能通过此子命令对该存储进行更改。通过此子命令所做的更改需要重新启动才能生效。 [...] path 将目标域内所有服务的 PATH 环境变量设置为字符串值。字符串值应符合 environ(7) 中为 PATH 环境变量概述的格式。请注意,如果服务指定了自己的 PATH,则特定于服务的环境变量将优先。注意:此工具不能用于为域内的所有服务设置通用环境变量。出于安全原因,特意将其限定为 PATH 环境变量,仅此而已。

我已经确认这适用于从 Finder 启动的 GUI 应用程序(它使用 getenv 获取 PATH)。请注意,您只需执行一次,更改将在重新启动后保持不变。


它也适用于我。 sudo launchctl procinfo <gui-pid> 显示新设置的 PATH 环境。但是 sudo launchctl config user path <new path> 实际上是为所有用户设置的......(通过添加新用户和使用 Sublime Text 的 python 控制台确认)
这似乎对登录时重新打开的应用程序的 PATH 环境变量没有影响(关闭时打开的应用程序)。
有趣的。这意味着对于将重新打开的应用程序,环境(或其子集)将被保存。
@MaxLeske 不,在更改环境变量之前正在启动重新打开的应用程序。因此,这不仅仅是在执行 sudo launchctl config user path 之后第一次发生这种情况(您似乎在假设?)。
@ShlomiSchwartz launchctl 不允许 允许您设置任意环境变量。 PATH 变量是一个例外。
J
Jason T. Miller

虽然这里的答案不是“错误的”,但我会添加另一个:永远不要在 OS X 中对影响“所有进程”的环境变量进行更改,甚至在 shell 之外,对于给定用户以交互方式运行的所有进程。

以我的经验,对所有进程的 PATH 等环境变量进行全局更改,在 OS X 上比在 Windows 上更容易破坏。原因是,许多 OS X 应用程序和其他软件(可能尤其包括操作系统本身的组件)在底层依赖 UNIX 命令行工具,并假设系统提供的这些工具版本的行为,并且这样做时不一定使用绝对路径(类似的注释适用于动态加载的库和 DYLD_* 环境变量)。例如,考虑到有关替换 OS X 提供的解释器(如 Python 和 Ruby)版本的各种 Stack Overflow 问题的评分最高的答案通常说“不要这样做”。

在这方面,OS X 与其他类 UNIX 操作系统(例如,Linux、FreeBSD 和 Solaris)实际上并没有什么不同。 Apple 没有提供简单的方法来做到这一点的最可能原因是因为它破坏了一些东西。就 Windows 不太容易出现这些问题而言,这是由于两件事:(1) Windows 软件不像 UNIX 软件那样倾向于依赖命令行工具,以及 (2) 微软有由影响所有进程的更改引起的“DLL 地狱”和安全问题的历史如此广泛,以至于它们已经更改了较新 Windows 版本中动态加载的行为,以限制“全局”配置选项(如 PATH)的影响。

“蹩脚”与否,如果您将此类更改限制在较小的范围内,您将拥有一个更加稳定的系统。


告诉人们不要做他们要求如何做的事情并不是对他们提出的问题的回答。阻止人们这样做也是破坏性的。苹果的作案手法。
使用 LSEnvironment 键 developer.apple.com/library/archive/documentation/General/… 在 /Applications/App.app/Contents/Info.plist 中设置 PATH 可能是当前推荐的解决方案。
@DaveX 不,绝对不是。您不得修改 app bundle 的内容。这样做可能会导致应用程序无法启动(即使配置正确!),因为内容不再与代码签名匹配。
P
Peter Mortensen

有时,所有先前的答案都根本不起作用。如果您想在 Eclipse 或 IntelliJ IDEA 中访问系统变量(如 M2_HOME),那么在这种情况下唯一对我有用的是:

首先(第 1 步)编辑 /etc/launchd.conf 以包含这样的一行:“setenv VAR value”,然后(第 2 步)重新启动。

简单地修改 .bash_profile 是行不通的,因为在 OS X 中,应用程序不像在其他 Unix 中那样启动;它们不继承父级的 shell 变量。由于我不知道的原因,所有其他修改都不起作用。也许其他人可以澄清这一点。


从 Spotlight 或任何其他方式启动的应用程序都具有由其父进程读取的 /etc/launchd.conf,因此对于在所有应用程序和 shell 中设置环境变量的位置来说,这是一个有吸引力的选择。
请参阅我的另一个解决方案的答案,它可以避免重新启动 - stackoverflow.com/questions/135688/…
我的 MaxOS 10.6 机器没有 /etc/launchd.conf 文件。这是这个版本的新东西还是过时的东西?还是这台机器坏了?
R
Russell B

在追逐 Environment Variables preference pane 并发现链接已损坏并且在 Apple 网站上的搜索似乎表明他们已经忘记了它之后......我开始回到难以捉摸的启动过程的踪迹。

在我的系统(Mac OS X 10.6.8)上,似乎 environment.plist 中定义的变量被可靠地导出到从 Spotlight 启动的应用程序(通过 launchd)。我的麻烦是这些变量没有被导出到终端中的新 bash 会话中。即我有这里描述的相反问题。

注意: environment.plist 看起来像 JSON,而不是 XML,如前所述

我能够让 Spotlight 应用程序通过 editing ~/MacOSX/environment.plist 查看变量我能够通过将以下内容添加到我的 .profile 文件中来强制相同的变量进入新的终端会话:

eval $(launchctl export)

不是那么难以捉摸:RCenvironment
关于 launchctl 导出的好技巧。但我不会将其按原样放入 .profile 中。它会用不包含 /usr/local/bin 的 $PATH 覆盖您的 $PATH。但是您可以使用正则表达式来选择您感兴趣的变量:``eval $(launchctl export | grep '^my.*=')。
在我的新 Mountain Lion 机器(10.8.2)上,environment.plist 完全没有价值。请参阅马修的正确答案。这都是关于已启动和 launchctl 命令行应用程序以及 /etc/launchd.conf 的。您可以在终端窗口中使用 man launchdman launchctlman launchd.conf 自行阅读。很高兴 Apple 使手册页保持最新,即使 Mac 开发人员库有点滞后。
J
John Millikin

任何 Bash 启动文件 - ~/.bashrc~/.bash_profile~/.profile。在 GUI 应用程序中,还有一些名为 ~/.MacOSX/environment.plist 的奇怪文件用于环境变量。


P
Peter Mortensen

这是一种非常简单的方法来做你想做的事。就我而言,它让 Gradle 工作(对于 Android Studio)。

打开终端。

运行以下命令:sudo nano /etc/paths 或 sudo vim /etc/paths

出现提示时输入您的密码。

转到文件底部,然后输入要添加的路径。

按 Control + X 退出。

输入“Y”以保存修改后的缓冲区。

打开一个新的终端窗口,然后输入:echo $PATH

您应该会看到附加到 PATH 末尾的新路径。

我从这篇文章中得到了这些细节:

Add to the PATH on Mac OS X 10.8 Mountain Lion and up


c
courtlandj

就像马特柯蒂斯给出的答案一样,我通过launchctl设置环境变量,但我将它包装在一个名为export的函数中,这样每当我在我的.bash_profile中导出一个正常的变量时,它也是由launchctl设置的。这是我所做的:

我的 .bash_profile 仅包含一行,(这只是个人喜好。) source .bashrc 我的 .bashrc 有这个: function export() { builtin export "$@" if [[ ${#@} -eq 1 && " ${@//[^=]/}" ]] 然后启动ctl setenv "${@%%=*}" "${@#*=}" elif [[ ! "${@//[^ ]/}" ]] 然后 launchctl setenv "${@}" "${!@}" fi } export -f export 上面会重载 Bash 内置的 "export" 并导出所有内容通常(你会注意到我用它导出“export”!),然后通过launchctl为OS X应用程序环境正确设置它们,无论你使用以下任何一种:export LC_CTYPE=en_US.UTF-8 # ~$ launchctl getenv LC_CTYPE # en_US.UTF-8 PATH="/usr/local/bin:${PATH}" PATH="/usr/local/opt/coreutils/libexec/gnubin:${PATH}" 导出路径 # ~$ launchctl getenv PATH # /usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin export CXX_FLAGS="-mmacosx- version-min=10.9" # ~$ launchctl getenv CXX_FLAGS # -mmacosx-version-min=10.9 这样我就不必每次都将每个变量都发送到launchctl,我只需设置我的.bash_profile / .bashrc我想要的方式。打开终端窗口,使用 launchctl getenv myVar 检查您感兴趣的环境变量,更改 .bash_profile/.bashrc 中的某些内容,关闭终端窗口并重新打开它,再次使用 launchctl 检查变量,然后瞧,它改变了。同样,与后 Mountain Lion 世界的其他解决方案一样,对于任何可用于应用程序的新环境变量,您需要在更改后启动或重新启动它们。


有用的答案 - 谢谢。我刚刚更新了它,因为您的原始解决方案没有处理您设置的环境变量的值包含等号的情况(例如,CXX_FLAGS="-mmacosx-version-min=10.9"
@SteveBroberg - 只需一个字符更改即可修复 Bash 正则表达式,而无需 sed! (不要误会我的意思,我喜欢 sed,但这很有效,而且要短得多。)
我认为必须有更好的方法,但我不是 bash 大师,我无法用谷歌搜索 %%、## 是什么等。
P
Peter Mortensen

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

干得好:

http://www.apple.com/downloads/macosx/system_disk_utilities/environmentvariablepreferencepane.html


仍可在 RCenvironment 购买
C
Claudio Floreani

简洁明了每个文件的用途

~/.profile 每次启动 Terminal.app 时都会获取

~/.bashrc 是“传统上”设置 Bash 环境的所有导出语句的位置

/etc/paths 是 Mac OS 中的主文件,其中包含用于为所有用户构建 PATH 环境变量的默认路径列表

/etc/paths.d/ 包含包含其他搜索路径的文件

非终端程序不会像您的终端那样继承系统范围的 PATH 和 MANPATH 变量!要为特定用户启动的所有进程设置环境,从而使环境变量可用于 Mac OS X GUI 应用程序,必须在 ~/.MacOSX/environment.plist 中定义这些变量(Apple 技术问答 QA1067)

使用以下命令行将您的 environment.plist/etc/paths 同步:

defaults write $HOME/.MacOSX/environment PATH "$(tr '\n' ':' </etc/paths)"

/etc/paths.d/ 是我正在寻找的方法,因为我试图理解为什么我启动的每个进程在我的机器上的 PATH 环境中都有一个已安装组件的特定目录,但它无法正常工作其他。原来它位于 /etc/paths.d 下的文件中,/usr/libexec/path_helper 在启动新进程时使用该文件构造 PATH 环境变量。
P
Peter Mortensen

/etc/launchd.conf 不用于 OS X v10.10 (Yosemite)、OS X v10.11 (El Capitan)、macOS v10.12 (Sierra) 或 macOS v10.13 (High Sierra)。

launchctl 手册页:

/etc/launchd.conf file is no longer consulted for subcommands to run during early boot time;
this functionality was removed for security considerations.

Ask Different answer 中描述的方法对我有效(重启后):从 Dock 或 Spotlight 启动的应用程序继承了我在 ~/Library/LaunchAgents/my.startup.plist 中设置的环境变量。 (在我的例子中,我需要为 Sublime Text 插件设置 LANGen_US.UTF-8。)


在重新启动时,是否有一个加载顺序可以确保 my.startup.plist 在上次会话的应用程序重新启动之前已经加载?
P
Peter Mortensen

$PATH 变量也受制于 path_helper,后者又使用 /etc/paths 文件和 /etc/paths.d 中的文件。

PATH and other environment issues in Leopard (2008-11) 中有更详尽的说明


C
CodeOverRide

只是这样做非常简单快捷。首先从终端创建一个 ~/.bash_profile:

touch .bash_profile

然后

open -a TextEdit.app .bash_profile

添加

export TOMCAT_HOME=/Library/Tomcat/Home

保存文件,你就完成了。


完美。我遵循了 JAVA_HOME 的步骤,只是添加了 export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home 并真正快速成功!
太棒了@NarendraC!
P
Peter Mortensen

iOS 上的所有魔力只有在将 source 与文件一起使用时才能使用,您可以在其中导出环境变量。

例如:

您可以像这样创建一个文件:

export bim=fooo
export bom=bar

将此文件另存为 bimbom.env,然后执行 source ./bimbom.ev。瞧,你得到了你的环境变量。

检查它们:

echo $bim

F
Fernando Martínez

这很简单:

编辑 ~/.profile 并把你的变量如下

vim ~/.profile

在文件中:

MY_ENV_VAR=值

保存( :wq )重新启动终端(退出并再次打开)确保一切正常:

$ 回声 $MY_ENV_VAR $ 价值


P
Peter Mortensen

对于单个用户修改,请使用您列出的 ~/.profile 个。以下链接解释了 Bash 何时读取不同的文件。

http://telin.ugent.be/~slippens/drupal/bashrc_and_others

如果要为 gui 应用程序设置环境变量,则需要 ~/.MacOSX/environment.plist 文件


P
Peter Mortensen

好吧,我不确定 /etc/paths~/.MacOSX/environment.plist 文件。那些是新的。

但是对于 Bash,您应该知道每次新的 shell 调用都会执行 .bashrc,而 .bash_profile 只在启动时执行一次。

我不知道 Mac OS X 出现这种情况的频率有多高。我认为随着窗口系统启动所有内容,这种区别已经消失。

就个人而言,我通过创建一个包含我需要的所有内容的 .bashrc 文件来消除混淆,然后执行以下操作:

ln -s .bashrc .bash_profile

M
MiB

除了建议的方法之外,需要注意的一点是,至少在 OS X 10.5(Leopard)中,launchd.conf 中设置的变量将与 .profile 中的设置合并。我想这可能对 ~/.MacOSX/environment.plist 中的设置也有效,但我尚未验证。


P
Peter Mortensen

在 Mac OS 上设置 PATH 环境变量

打开终端程序(默认情况下,它位于您的 Applications/Utilities 文件夹中)。运行以下命令

touch ~/.bash_profile; open ~/.bash_profile

这将在您的默认文本编辑器中打开该文件。

以 Android SDK 为例:

您需要将路径添加到您的 Android SDK 平台工具和工具目录。在我的示例中,我将使用“/Development/android-sdk-macosx”作为安装 SDK 的目录。添加以下行:

export PATH=${PATH}:/Development/android-sdk-macosx/platform-tools:/Development/android-sdk-macosx/tools

保存文件并退出文本编辑器。执行您的 .bash_profile 以更新您的 PATH:

source ~/.bash_profile

现在,每次打开终端程序时,您的 PATH 都将包含 Android SDK。


P
Peter Mortensen

这很简单。编辑文件 .profile(vi、nanoSublime Text 或其他文本编辑器)文件。您可以在 ~/ 目录(用户目录)中找到它并设置如下:

export MY_VAR=[your value here]

Java 主页示例:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/current

保存并返回终端。

您可以使用以下方法重新加载它:

source .profile

或者关闭并打开您的终端窗口。


B
Ben Carp

2022 年 2 月(MacOs 12+)

此处的解决方案应该在重新启动或应用程序重新启动后工作。

命令行界面

打开您选择的 CLI 配置文件。

对于 bash 打开 ~/.bash_profile

对于 zsh 打开 ~/.zshrc

添加(或替换)

export varName=varValue 

(如果 varValue 中有空格 - 将其包装在 " 中)

确保重新启动命令行应用程序。

图形用户界面

完成 CLI 步骤。确保 GUI 应用程序已关闭。从命令行打开 GUI 应用程序。例如:

open /Applications/Sourcetree.app

(您也可以在 .zshrc 中为该命令设置别名)

原则

Mac 没有为所有上下文设置环境变量的配置选项。

避免更改用户配置文件之外的任何内容。

不再工作了

launchctl config user varName varVal (MacOS 12.1+)

编辑 /etc/launchd.conf

带有 plist 后缀的 xml 文件


是否可以为特定的启动服务设置环境变量?
P
Peter Mortensen

这里有两种类型的炮弹。

非登录:每次启动新的 Bash 副本时都会重新加载 .bashrc

登录:仅当您登录或明确告诉 Bash 加载它并将其用作登录 shell 时才会加载 .profile。

在此重要的是要了解,对于 Bash,文件 .bashrc 只能由交互式和非登录的 shell 读取,并且您会发现人们经常在 .bash_profile 中加载 .bashrc 以克服此限制。

现在您已经有了基本的了解,让我们继续讨论我将如何建议您进行设置。

.profile:创建它不存在。把你的 PATH 设置放在那里。

.bashrc:如果不存在则创建。把你所有的别名和自定义方法放在那里。

.bash_profile:如果不存在则创建。将以下内容放入其中。

.bash_file:

#!/bin/bash
source ~/.profile # Get the PATH settings
source ~/.bashrc  # Get Aliases and Functions
#

P
Peter Mortensen

登录外壳

/etc/profile

shell 首先执行文件 /etc/profile 中的命令。使用 root 权限的用户可以设置这个文件来为运行 Bash 的用户建立系统范围的默认特性。

.bash_profile
.bash_login
.profile

接下来,shell 会按顺序查找 ~/.bash_profile~/.bash_login~/.profile(~/ 是您的主目录的简写),并执行它找到的第一个文件中的命令。您可以将命令放在这些文件之一中以覆盖 /etc/profile 中设置的默认值。在虚拟终端上运行的 shell 不会执行这些文件中的命令。

.bash_logout

当您注销时,bash 会执行 ~/.bash_logout 文件中的命令。该文件通常包含在会话后清理的命令,例如删除临时文件的命令。

交互式非登录外壳

/etc/bashrc

尽管 bash 不直接调用,但许多 ~/.bashrc 文件调用 /etc/bashrc。此设置允许使用 root 权限的用户为非登录 bash shell 建立系统范围的默认特征。

.bashrc

交互式非登录 shell 执行 ~/.bashrc 文件中的命令。通常,登录 shell 的启动文件(例如 .bash_profile)运行此文件,因此登录和非登录 shell 都运行 .bashrc 中的命令。

因为 .bashrc 中的命令可能会执行多次,并且因为子 shell 继承导出的变量,所以最好将添加到现有变量的命令放在 .bash_profile 文件中。