macos - shell设置环境变量 - 环境变量文件




在OS X中设置环境变量? (20)

如何为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 for bash or zsh 。

重新启动后如何保持更改

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

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

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

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

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

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

在OSX中修改环境变量(如PATH)的正确方法是什么? 我看了一下Google,找到了3个不同的文件来编辑:

  • 的/ etc /路径
  • 〜/ .profile文件
  • 〜/ .tcshrc文件

我甚至没有这些文件,而且我很确定.tcshrc是错误的,因为OSX现在使用了bash。 任何人都知道这些变量,特别是PATH的定义?

编辑:我正在运行OS X 10.5


来自单一来源的命令行和GUI应用程序解决方案(适用于优胜美地和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"

我们需要一个Launch Agent ,它可以在每次登录时随时运行,并随时按需将这些变量加载到用户会话中。 我们还需要一个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参数非常关键; 需要使用登录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)来说。


Setup your PATH environment variable on Mac OS

Open the Terminal program (this is in your Applications/Utilites folder by default). Run the following command touch ~/.bash_profile; open ~/.bash_profile This will open the file in the your default text editor.

For ANDROID SDK as example :

You need to add the path to your Android SDK platform-tools and tools directory. In my example I will use "/Development/android-sdk-macosx" as the directory the SDK is installed in. Add the following line:

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

Save the file and quit the text editor. Execute your .bash_profile to update your PATH.

source ~/.bash_profile

Now everytime you open the Terminal program you PATH will included the Android SDK.


更新(2017-08-04)

从(至少)macOS 10.12.6(Sierra)开始,这种方法似乎已经停止了Apache httpd的工作(对于systemlaunchctl configuser选项)。 其他程序似乎不受影响。 可以想象,这是httpd中的一个错误。

原始答案

这涉及到OS X 10.10+(特别是由于rootless模式,其中/usr/bin不再可写入)。

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

sudo launchctl config user path <new path>

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

配置系统| 用户参数值

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

[...]

路径

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

注意:此设施不能用于设置域内所有服务的常规环境变量。 由于安全原因,它被有意限定在PATH环境变量中。

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



Login Shells

/etc/profile

The shell first executes the commands in /etc/profile. A user working with root privileges can set up this file to establish systemwide default characteristics for users running bash.

.bash_profile 
.bash_login 
.profile

Next the shell looks for ~/.bash_profile, ~/.bash_login, and ~/.profile (~/ is short- hand for your home directory), in that order, executing the commands in the first of these files it finds. You can put commands in one of these files to override the defaults set in /etc/profile. A shell running on a virtual terminal does not execute commands in these files.

.bash_logout

When you log out, bash executes commands in the ~/.bash_logout file. This file often holds commands that clean up after a session, such as those that remove temporary files.

Interactive Nonlogin Shells

/etc/bashrc

Although not called by bash directly, many ~/.bashrc files call /etc/bashrc. This setup allows a user working with root privileges to establish systemwide default characteristics for nonlogin bash shells.

.bashrc

An interactive nonlogin shell executes commands in the ~/.bashrc file. Typically a startup file for a login shell, such as .bash_profile, runs this file, so both login and nonlogin shells run the commands in .bashrc.

Because commands in .bashrc may be executed many times, and because subshells inherit exported variables, it is a good idea to put commands that add to existing variables in the .bash_profile file.


Here is a very simple way to do what you want. In my case, it was getting gradle to work (for Android Studio )

  • Open up Terminal.
  • Run the following command:

    sudo nano /etc/paths or sudo vim /etc/paths

  • Enter your password, when prompted.

  • Go to the bottom of the file, and enter the path you wish to add.
  • Hit control-x to quit.
  • Enter 'Y' to save the modified buffer.
  • Open a new terminal window then type:

    echo $PATH

You should see the new path appended to the end of the PATH

I got these details from this post:

http://architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion/#.UkED3rxPp3Q

I hope that can help someone else



Just did this really easy and quick. First create a ~/.bash_profile from terminal:

touch .bash_profile

然后

open -a TextEdit.app .bash_profile

export TOMCAT_HOME=/Library/Tomcat/Home

save documement and you are done.


One thing to note in addition to the approaches suggested is that, in OS X 10.5 at least, the variables set in launchd.conf will be merged with the settings made in .profile. I suppose this is likely to be valid for the settings in ~/.MacOSX/environment.plist too, but I haven't verified.


To be concise and clear about what each file is intended for

  • ~/.profile is sourced every time Terminal.app is launched
  • ~/.bashrc is where "traditionally" all the export statements for Bash environment are set
  • /etc/paths is the main file in Mac OS that contains the list of default paths for building the PATH environment variable for all users
  • /etc/paths.d/ contains files that hold additional search paths

Non-terminal programs don't inherit the system wide PATH and MANPATH variables that your terminal does! To set environment for all processes launched by a specific user, thus making environment variables available to Mac OS X GUI applications, those variables must be defined in your ~/.MacOSX/environment.plist (Apple Technical Q&A QA1067)

Use the following command line to synchronize your environment.plist with /etc/paths :

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

for a single user modification, use ~/.profile of the ones you listed, the following link explains when the different files are read by bash

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

if you want to set the environment variable for gui applications you need the ~/.MacOSX/environment.plist file


well, I'm unsure about /etc/paths and ~/.MacOSX/environment.plist those are new.

But with bash, you should know that .bashrc is executed with every new shell invocation and .bash_profile is only executed once at startup. Don't know how often this is with macos, I think the distinction has broken down with the window system launching everything.

Personally, I eliminate the confusion by creating a .bashrc with everything I need and then do:

ln -s .bashrc .bash_profile

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


在Mountain Lion上,所有/etc/paths/etc/launchd.conf编辑都不起作用!

苹果的开发者论坛说:

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

〜/ .MacOSX / environment.plist不再受支持。“

所以我直接编辑了应用程序的Info.plist (右键单击“AppName.app”(在这种情况下是SourceTree),然后是“ Show package contents ”)

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

<key>LSEnvironment</key>
<dict>
     <key>PATH</key>
     <string>/Users/flori/.rvm/gems/ruby-1.9.3-p362/bin:/Users/flori/.rvm/gems/[email protected]/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>

(请参阅: Apple的LaunchServicesKeys文档

现在应用程序(在我的情况下,SourceTree)使用给定的路径,并与git 1.9.3一起工作:-)

PS:当然,你必须调整路径条目以满足你特定的路径需求。


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

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

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

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

细节:

登录项目: ~/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设备)分成一个单独的脚本。


就像Matt Curtis给出的答案一样,我通过launchctl设置了环境变量,但是我将它包装在一个名为export的函数中,这样每当我在.bash_profile中导出一个像普通变量的变量时,它也由launchctl设置。 这是我做的事情:

  1. 我的.bash_profile只包含一行,(这只是个人偏好。)

    source .bashrc
    
  2. 我的.bashrc有这样的:

    function export()
    {
        builtin export "[email protected]"
        if [[ ${#@} -eq 1 && "${@//[^=]/}" ]]
        then
            launchctl setenv "${@%%=*}" "${@#*=}"
        elif [[ ! "${@//[^ ]/}" ]]
        then
            launchctl setenv "${@}" "${[email protected]}"
        fi
    }
    
    export -f export
    
  3. 上面的内容会使Bash内建的“导出”过载,并且会正常导出所有内容(您会注意到我会导出“导出”!),然后通过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}"
    export 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
    
  4. 这样我就不必每次都发送每个变量来启动launchctl,并且我可以按照我的需要设置我的.bash_profile / .bashrc。 打开终端窗口,使用launchctl getenv myVar检查您感兴趣的环境变量,在.bash_profile / .bashrc中更改某些内容,关闭终端窗口并重新打开它,再次使用launchctl和voilá检查该变量,它改变了。

  5. 再次,像山后狮子世界的其他解决方案一样,对于应用程序可用的任何新环境变量,您需要在更改后启动或重新启动它们。


尽管这里的答案并不是“错误的”,但我会补充一点:不要在OS X中影响“所有进程”甚至是在shell之外进行环境变量更改,以便给定用户交互式运行所有进程。

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

在这方面,OS X与其他类UNIX操作系统(如Linux,FreeBSD和Solaris)没有区别; 苹果不提供简单的方法来做到这一点的最可能的原因是因为它打破了一切 。 在Windows不太容易出现这些问题的情况下,这是由于以下两点:(1)Windows软件并不倾向于依赖命令行工具来实现UNIX软件,(2)Microsoft已经如此广泛的“DLL地狱”历史以及由于更改而导致的安全问题,这些更改会影响所有在较新的Windows版本中改变动态加载行为的进程,从而限制“全局”配置选项(如PATH)的影响。

“跛脚”或没有,如果你将这种改变限制在较小的范围内,你将会有一个更加稳定的系统。


有时候所有以前的答案都不起作用。 如果你想在Eclipse或IntelliJ中访问系统变量(如M2_HOME),在这种情况下唯一适用于我的是:

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

简单修改.bash_profile将不起作用,因为在osx中​​应用程序不像其他UNIX中那样启动,它们不会继承父项shell变量。 所有其他修改都不适用于我未知的原因。 也许别人可以澄清这一点。


这很简单:

Edit ~/.profile and put your variables as follow

$ vim ~/.profile

In file put:

MY_ENV_VAR=value

  1. Save ( :wq )

  2. Restart the terminal (Quit and open it again)

  3. Make sure that`s all be fine:

$ echo $MY_ENV_VAR

$ value







environment-variables