bash 在 OS X 上设置环境变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/135688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:42:06  来源:igfitidea点击:

Setting environment variables on OS X

macosbashpathenvironment-variables

提问by Paul Wicks

What is the proper way to modify environment variables like PATH in OS X?

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

I've looked on Google a little bit and found three different files to edit:

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

  • /etc/paths
  • ~/.profile
  • ~/.tcshrc
  • /etc/路径
  • ~/.profile
  • ~/.tcshrc

I don't even have some of these files, and I'm pretty sure that .tcshrcis wrong, since OS X uses bash now. Where are these variables, especially PATH, defined?

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

I'm running OS X v10.5(Leopard).

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

回答by Matthew McCullough

Bruno is right on track. I've done extensive research and if you want to set variables that are available in all GUI applications, your only option is /etc/launchd.conf.

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

Please note that environment.plist does not work for applications launched via Spotlight. This is documented by Steve Sexton here.

请注意,environment.plist 不适用于通过 Spotlight 启动的应用程序。这是由 Steve Sexton 在这里记录的

  1. Open a terminal prompt

  2. Type sudo vi /etc/launchd.conf(note: this file might not yet exist)

  3. Put contents like the following into the file

    # Set environment variables here so they are available globally to all apps
    # (and Terminal), including those launched via Spotlight.
    #
    # After editing this file run the following command from the terminal to update
    # environment variables globally without needing to reboot.
    # NOTE: You will still need to restart the relevant application (including
    # Terminal) to pick up the changes!
    # grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl
    #
    # See http://www.digitaledgesw.com/node/31
    # and http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x/
    #
    # Note that you must hardcode the paths below, don't use environment variables.
    # You also need to surround multiple values in quotes, see MAVEN_OPTS example below.
    #
    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
    
  4. Save your changes in vi and reboot your Mac. Or use the grep/xargscommand which is shown in the code comment above.

  5. Prove that your variables are working by opening a Terminal window and typing exportand you should see your new variables. These will also be available in IntelliJ IDEA and other GUI applications you launch via Spotlight.

  1. 打开终端提示

  2. 类型sudo vi /etc/launchd.conf(注意:此文件可能尚不存在)

  3. 将如下内容放入文件中

    # Set environment variables here so they are available globally to all apps
    # (and Terminal), including those launched via Spotlight.
    #
    # After editing this file run the following command from the terminal to update
    # environment variables globally without needing to reboot.
    # NOTE: You will still need to restart the relevant application (including
    # Terminal) to pick up the changes!
    # grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl
    #
    # See http://www.digitaledgesw.com/node/31
    # and http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x/
    #
    # Note that you must hardcode the paths below, don't use environment variables.
    # You also need to surround multiple values in quotes, see MAVEN_OPTS example below.
    #
    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
    
  4. 在 vi 中保存更改并重新启动 Mac。或者使用上面代码注释中显示的grep/xargs命令。

  5. 通过打开终端窗口并键入来证明您的变量正在工作export,您应该会看到您的新变量。这些也将在 IntelliJ IDEA 和您通过 Spotlight 启动的其他 GUI 应用程序中可用。

回答by Matt Curtis

How to set the environment for new processes started by Spotlight (without needing to reboot)

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

You can set the environment used by launchd (and, by extension, anything started from Spotlight) with launchctl setenv. For example to set the path:

您可以使用launchctl setenv. 例如设置路径:

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

Or if you want to set up your path in .bashrcor similar, then have it mirrored in launchd:

或者,如果你想在.bashrc或类似的地方设置你的路径,然后在launchd中镜像:

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

There's no need to rebootthough you will need to restart an app if you want it to pick up the changed environment.

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

This includes any shells already running under Terminal.app, although if you're there you can set the environment more directly, e.g. with export PATH=/opt/local/bin:/opt/local/sbin:$PATHfor bash or zsh.

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

How to keeping changes after a reboot

重新启动后如何保持更改

To keep changes after a rebootyou can set the environment variables from /etc/launchd.conf, like so:

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

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

launchd.confis executed automatically when you reboot.

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

If you want these changes to take effect now, you should use this command to reprocess launchctl.conf(thanks @mklement for the tip!)

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

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

You can find out more about launchctland how it loads launchd.confwith the command man launchctl.

您可以通过命令了解更多信息launchctl以及它是如何加载launchd.confman launchctl

回答by tim_yates

Up to and including OS X v10.7(Lion)you can set them in:

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

~/.MacOSX/environment.plist

See:

看:

For PATH in the Terminal, you should be able to set in .bash_profileor .profile(you'll probably have to create it though)

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

For OS X v10.8(Mountain Lion) and beyondyou need to use launchdand launchctl.

对于OS X v10.8(Mountain Lion) 及更高版本,您需要使用launchdlaunchctl.

回答by Ersin Er

Solution for both command line and GUI applications from a single source (works with Mac OS X v10.10(Yosemite) and Mac OS X v10.11(El Capitan))

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

Let's assume you have environment variable definitions in your ~/.bash_profilelike in the following snippet:

假设您~/.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"

We need a Launch Agentwhich will run on each login and anytime on demand which is going to load these variables to the user session. We'll also need a shell script to parse these definitions and build necessary commands to be executed by the agent.

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

Create a file with plistsuffix (e.g. named osx-env-sync.plist) in ~/Library/LaunchAgents/directory with the following contents:

在目录中创建一个带有plist后缀(例如 named osx-env-sync.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>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>

-lparameter is critical here; it's necessary for executing the shell script with a login shellso that ~/.bash_profileis sourced in the first place before this script is executed.

-l参数在这里很关键;使用登录 shell执行 shell 脚本是必要的,以便~/.bash_profile在执行此脚本之前首先获取它。

Now, the shell script. Create it at ~/.osx-env-sync.shwith the following contents:

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

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

Make sure the shell script is executable:

确保 shell 脚本是可执行的:

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

Now, load the launch agent for current session:

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

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

(Re)Launch a GUI application and verify that it can read the environment variables.

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

The setup is persistent. It will survive restarts and relogins.

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

After the initial setup (that you just did), if you want to reflect any changes in your ~/.bash_profileto your whole environment again, rerunning the launchctl load ...command won't perform what you want; instead you'll get a warning like the following:

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

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

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

In order to reload your environment variables without going through the logout/login process do the following:

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

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

Finally make sure that you relaunch your already running applications (including Terminal.app) to make them aware of the changes.

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

I've also pushed the code and explanations here to a GitHub project: osx-env-sync.

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

I hope this is going to be the ultimate solution, at least for the latest versions of OS X (Yosemite & El Capitan).

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

回答by WoooHaaaa

  1. Do:

    vim ~/.bash_profile
    

    The file may not exist (if not, you can just create it).

  2. Type in this and save the file:

    export PATH=$PATH:YOUR_PATH_HERE
    
  3. Run

    source ~/.bash_profile
    
  1. 做:

    vim ~/.bash_profile
    

    该文件可能不存在(如果不存在,您可以创建它)。

  2. 输入这个并保存文件:

    export PATH=$PATH:YOUR_PATH_HERE
    
  3. source ~/.bash_profile
    

回答by pajato0

There are essentially two problems to solve when dealing with environment variables in OS X. The first is when invoking programs from Spotlight (the magnifying glass icon on the right side of the Mac menu/status bar) and the second when invoking programs from the Dock. Invoking programs from a Terminal application/utility is trivial because it reads the environment from the standard shell locations (~/.profile, ~/.bash_profile, ~/.bashrc, etc.)

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

When invoking programs from the Dock, use ~/.MacOSX/environment.plistwhere the <dict>element contains a sequence of <key>KEY</key><string>theValue</string>elements.

从 Dock 调用程序时,使用~/.MacOSX/environment.plistwhere<dict>元素包含<key>KEY</key><string>theValue</string>元素序列 。

When invoking programs from Spotlight, ensure that launchd has been setup with all the key/value settings you require.

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

To solve both problems simultaneously, I use a login item (set via the System Preferences tool) on my User account. The login item is a bash script that invokes an Emacs lisp function although one can of course use their favorite scripting tool to accomplish the same thing. This approach has the added benefit that it works at any time and does not require a reboot, i.e. one can edit ~/.profile, run the login item in some shell and have the changes visible for newly invoked programs, from either the Dock or Spotlight.

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

Details:

细节:

Login item: ~/bin/macosx-startup

登录项: ~/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 function: ~/lib/emacs/elisp/macosx/envionment-support.el

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

NOTE: This solution is an amalgam of those coming before I added mine, particularly that offered by Matt Curtis, but I have deliberately tried to keep my ~/.bash_profilecontent platform independent and put the setting of the launchdenvironment (a Mac only facility) into a separate script.

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

回答by Big Rich

Another, free, opensource, Mac OS X v10.8 (Mountain Lion) Preference pane/environment.plist solution is EnvPane.

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

EnvPane's source codeavailable on GitHub. EnvPane looks like it has comparable features to RCEnvironment, however, it seems it can update its stored variables instantly, i.e. withoutthe need for a restart or login, which is welcome.

EnvPane 的源代码可在GitHub 上获得。EnvPane 看起来具有与RCEnvironment相当的功能,但是,它似乎可以立即更新其存储的变量,即无需重新启动或登录,这是受欢迎的。

As stated by the developer:

正如开发商所说:

EnvPane is a preference pane for Mac OS X 10.8 (Mountain Lion) that lets you set environment variables for all programs in both graphical and terminal sessions. Not only does it restore support for ~/.MacOSX/environment.plist in Mountain Lion, it also publishes your changes to the environment immediately, without the need to log out and back in. <SNIP> EnvPane includes (and automatically installs) a launchd agent that runs 1) early after login and 2) whenever the ~/.MacOSX/environment.plist changes. The agent reads ~/.MacOSX/environment.plist and exports the environment variables from that file to the current user's launchd instance via the same API that is used by launchctl setenv and launchctl unsetenv.

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

Disclaimer: I am in no way related to the developer or his/her project.

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

P.S. I like the name (sounds like 'Ends Pain').

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

回答by Flori

On Mountain Lion all the /etc/pathsand /etc/launchd.confediting doesn't make any effect!

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

Apple's Developer Forums say:

Apple 的开发者论坛说:

"Change the Info.plist of the .app itself to contain an "LSEnvironment" dictionary with the environment variables you want.

~/.MacOSX/environment.plist is no longer supported."

“更改 .app 本身的 Info.plist 以包含具有所需环境变量的“LSEnvironment”字典。

~/.MacOSX/environment.plist 不再受支持。”

So I directly edited the application's Info.plist(right click on "AppName.app" (in this case SourceTree) and then "Show package contents").

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

Show Package Contents

显示包裹内容

And I added a new key/dict pair called:

我添加了一个新的键/字典对,名为:

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

(see: LaunchServicesKeys Documentation at Apple)

(请参阅:Apple 的 LaunchServicesKeys 文档

Enter image description here

在此处输入图片说明

Now the application (in my case Sourcetree) uses the given path and works with Git 1.9.3 :-)

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

PS: Of course you have to adjust the Path entry to your specific path needs.

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

回答by Max Leske

Update (2017-08-04)

更新 (2017-08-04)

As of (at least) macOS 10.12.6 (Sierra) this method seems to have stopped working for Apache httpd (for both the systemand the useroption of launchctl config). Other programs do not seem to be affected. It is conceivable that this is a bug in httpd.

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

Original answer

原答案

This concerns OS X 10.10+ (10.11+ specifically due to rootless mode where /usr/binis no longer writeable).

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

I've read in multiple places that using launchctl setenv PATH <new path>to set the PATHvariable does not work due to a bug in OS X (which seems true from personal experience). I found that there's another way the PATHcan be set for applications not launched from the shell:

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

sudo launchctl config user path <new path>

This option is documented in the launchctl man page:

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

config system | user parameter value

Sets persistent configuration information for launchd(8) domains. Only the system domain and user domains may be configured. The location of the persistent storage is an implementation detail, and changes to that storage should only be made through this subcommand. A reboot is required for changes made through this subcommand to take effect.

[...]

path

Sets the PATH environment variable for all services within the target domain to the string value. The string value should conform to the format outlined for the PATH environment variable in environ(7). Note that if a service specifies its own PATH, the service-specific environment variable will take precedence.

NOTE: This facility cannot be used to set general environment variables for all services within the domain. It is intentionally scoped to the PATH environment vari- able and nothing else for security reasons.

配置系统| 用户参数值

为 launchd(8) 域设置持久配置信息。只能配置系统域和用户域。持久存储的位置是一个实现细节,对该存储的更改只能通过此子命令进行。通过此子命令所做的更改需要重新启动才能生效。

[...]

小路

将目标域内所有服务的 PATH 环境变量设置为字符串值。字符串值应符合environ(7) 中为PATH 环境变量概述的格式。请注意,如果服务指定了自己的 PATH,则服务特定的环境变量将优先。

注意:此工具不能用于为域内的所有服务设置通用环境变量。出于安全原因,它有意将范围限定在 PATH 环境变量中,而没有其他任何目的。

I have confirmed this to work with a GUI application started from Finder (which uses getenvto get PATH). Note that you only have to do this once and the change will be persistent through reboots.

我已经确认这可以与从 Finder(getenv用于获取 PATH)启动的 GUI 应用程序一起使用。请注意,您只需执行此操作一次,更改将通过重新启动保持不变。

回答by Jason T. Miller

While the answers here aren't "wrong", I'll add another: never make environment variable changes in OS X that affect "all processes", or even, outside the shell, for all processes run interactively by a given user.

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

In my experience, global changes to environment variables like PATH for all processes are even more likely to break things on OS X than on Windows. Reason being, lots of OS X applications and other software (including, perhaps especially, components of the OS itself) rely on UNIX command-line tools under the hood, and assume the behavior of the versions of these tools provided with the system, and don't necessarily use absolute paths when doing so (similar comments apply to dynamically-loaded libraries and DYLD_* environment variables). Consider, for instance, that the highest-rated answers to various Stack Overflow questions about replacing OS X-supplied versions of interpreters like Python and Ruby generally say "don't do this."

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

OS X is really no different than other UNIX-like operating systems (e.g., Linux, FreeBSD, and Solaris) in this respect; the most likely reason Apple doesn't provide an easy way to do this is because it breaks things. To the extent Windows isn't as prone to these problems, it's due to two things: (1) Windows software?doesn't tend to rely on command-line tools to the extent that UNIX software does, and (2) Microsoft has had such an extensive history of both "DLL hell" and security problems caused by changes that affect all processes that they've changed the behavior of dynamic loading in newer Windows versions to limit the impact of "global" configuration options like PATH.

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

"Lame" or not, you'll have a far more stable system if you restrict such changes to smaller scopes.

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