Setting environment variables in OS X?

Paul Wicks Source

What is the proper way to modify environment variables like PATH in OSX? I've looked on Google a little bit and found 3 different files to edit:

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

I don't even have some of these files, and I'm pretty sure that .tcshrc is wrong, since OSX uses bash now. Anybody have any idea where these variables, especially PATH, are defined?

Edit: I'm running OS X 10.5



answered 10 years ago tim_yates #1

Up to and including Lion (10.7) you can set them in



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

For Mountain lion and beyond you need to use launchd and launchctl

answered 10 years ago John Millikin #2

Any of the Bash startup files -- ~/.bashrc, ~/.bash_profile, ~/.profile. There's also some sort of weird file named ~/.MacOSX/environment.plist for environment variables in GUI applications.

answered 10 years ago mmaibaum #3

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

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

answered 10 years ago mike511 #4

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

answered 9 years ago Bruno Ranschaert #5

Sometimes all of the previous answers simply don't work. If you want to have access to a system variable (like M2_HOME) in Eclipse or in IntelliJ the only thing that works for me in this case is:

First (step 1) edit /etc/launchd.conf to contain a line like this: "setenv VAR value" and then (step 2) reboot.

Simply modifying .bash_profile won't work because in osx the applications are not started as in other UNIX'es, they don't inherit the parents shell variables. All the other modifications won't work for a reason that is unknown to me. Maybe someone else can clarify about this.

answered 9 years ago Matthew McCullough #6

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

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

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
# and
# Note that you must hardcode the paths below, don't use enviroment 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/xargs command which is shown in the code comment above.

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

answered 8 years ago Matt Curtis #7

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

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 PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

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

launchctl setenv PATH $PATH

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

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

How to keeping changes after a reboot

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

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

launchd.conf is executed automatically when you reboot.

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

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

You can find out more about launchctl and how it loads launchd.conf with the command man launchctl.

answered 7 years ago Tom Teman #8

I think what the OP is looking for is a simple, windows-like solution.

here ya go:

answered 7 years ago MiB #9

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.

answered 7 years ago pajato0 #10

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

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

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

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.


Login item: ~/bin/macosx-startup

bash -l -c "/Applications/ --batch -l ~/lib/emacs/elisp/macosx/environment-support.el -f generate-environment"

Emacs lisp function: ~/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>")
    (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.

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_profile content platform independent and put the setting of the launchd environment (a Mac only facility) into a separate script.

answered 7 years ago Russell B #11

After chasing the Environment Variables preference pane and discovering that the link is broken and a search on Apple's site seems to indicate they've forgotten about it... I started back onto the trail of the elusive launchd process.

On my system (Mac OS X 10.6.8) it appears that variables defined in environment.plist are being reliably exported to apps launched from Spotlight (via launchd). My trouble is that those vars are not being exported to new bash sessions in Terminal. I.e. I have the opposite problem as portrayed here.

NOTE: environment.plist looks like JSON, not XML, as described previously

I was able to get Spotlight apps to see the vars by editing ~/MacOSX/environment.plist and I was able to force the same vars into a new Terminal session by adding the following to my .profile file:

eval $(launchctl export)

answered 7 years ago Rabi #12

For Bash, try adding your environment variables to the file /etc/profile to make them available for all users. No need to reboot, just start a new Terminal session.

answered 6 years ago MrROY #13


vim ~/.bash_profile

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

2.type in this and save the file:


source ~/.bash_profile

answered 6 years ago Nicolas Wu #14

the $PATH variable is also subject to path_helper, which in turn makes use of the /etc/paths file and files in /etc/paths.d.

A more thorough description can be found here:

answered 6 years ago Jason T. Miller #15

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.

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

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.

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

answered 5 years ago Big Rich #16

Another, free, opensource, Mac OSX Mountain Lion (10.8) Preference pane/environment.plist solution is EnvPane.

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

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

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

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

answered 5 years ago Flori #17

On Mountain Lion all the /etc/paths and /etc/launchd.conf editing doesn't take any effect!

Apple's Developer Forums say:

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

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

Show Package Contents

and added a new key/dict pair called:

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

(see: LaunchServicesKeys Documentation at Apple)

enter image description here

now the App (in my case SourceTree) uses the given path and works with git 1.9.3 :-)

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

answered 5 years ago wired00 #18

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:

I hope that can help someone else

answered 4 years ago Charaf JRA #19

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.

answered 4 years ago Fernando Martínez #20

It's simple:

Edit ~/.profile and put your variables as follow

$ vim ~/.profile

In file put:


  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

answered 4 years ago francois.robert #21

It's quite simple, edit .profile (vi, nano, sublimeText or other text editor) file, you can found it at ~/ directory (user directory) and set like this :

export MY_VAR=[your value here]

exemple with java home :

export JAVA_HOME=/Library/Java/JavaVirtualMachines/current

save it and return to the terminal.

You can reload it with :

source .profileor close / open your terminal window.

answered 4 years ago courtlandj #22

Much like the answer Matt Curtis gave, I set environment variables via launchctl, but I wrap it in a function called export, so that whenever I export a variable like normal in my .bash_profile, it is also set by launchctl. Here is what I do:

  1. My .bash_profile consists solely of one line, (This is just personal preference.)

    source .bashrc
  2. My .bashrc has this:

    function export()
        builtin export "[email protected]"
        if [[ ${#@} -eq 1 && "${@//[^=]/}" ]]
            launchctl setenv "${@%%=*}" "${@#*=}"
        elif [[ ! "${@//[^ ]/}" ]]
            launchctl setenv "${@}" "${[email protected]}"
    export -f export
  3. The above will overload the Bash builtin "export" and will export everything normally (you'll notice I export "export" with it!), then properly set them for OS X app environments via launchctl, whether you use any of the following:

    export LC_CTYPE=en_US.UTF-8
    # ~$ launchctl getenv LC_CTYPE
    # en_US.UTF-8
    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. This way I don't have to send every variable to launchctl every time, and I can just have my .bash_profile / .bashrc set up the way I want. Open a terminal window, check out your environment variables you're interested in with launchctl getenv myVar, change something in your .bash_profile/.bashrc, close the terminal window and re-open it, check the variable again with launchctl, and voilá, it's changed.

  5. Again, like the other solutions for the post-Mountain Lion world, for any new environment variables to be available for apps, you need to launch or re-launch them after the change.

answered 4 years ago CodeOverRide #23

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

touch .bash_profile


open -a .bash_profile


export TOMCAT_HOME=/Library/Tomcat/Home

save documement and you are done.

answered 3 years ago Claudio Floreani #24

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

  • ~/.profile is sourced every time 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)"

answered 3 years ago ZOXIS #25

There are two type of shells at play here.

  • Non-Login: .bashrc is reloaded every time you start a new copy of bash
  • Login: The .profile is loaded only when you either login, or explicitly tell bash to load it and use it as a login shell.

Its important to understand here that with bash .bashrc is only read by a shell that's both interactive and non-login, and you will find that people often load .bashrc in .bash_profile to overcome this limitation.

Now that you have the basic understanding, lets move on to how i would advice you to set it up.

  • .profile: create it non-existing. Put your PATH setup in there.
  • .bashrc: create if non-existing. Put all your Aliases and Custom method in there.
  • .bash_profile: create if non-existing. Put the following in there.


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

answered 3 years ago Koray Tugay #26

Login Shells


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.


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.


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


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.


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.

answered 3 years ago Ersin Er #27

Solution for both command line and GUI apps from a single source (works with Yosemite & El Capitan)

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

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 Agent which 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.

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

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

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

Now, the shell script. Create it at ~/ with the following contents:

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

Make sure the shell script is executable:

chmod +x ~/

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.

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_profile to your whole environment again, rerunning the launchctl load ... command won't perform what you want; instead you'll get a warning like the following:

<$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 to make them aware of the changes.

I've also pushed the code and explanations here to a GitHub project: 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).

answered 3 years ago Max Leske #28

Update (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 system and the user option of launchctl config). Other programs do not seem to be affected. It is conceivable that this is a bug in httpd.

Original answer

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

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

sudo launchctl config user path <new path>

This option is documented in the launchctl man page:

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.



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.

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

answered 4 months ago David #29

/etc/launchd.conf is not used in Yosemite, El Capitain, or (High) Sierra

From the launchctl man page:

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

The method described in this Ask Different answer works for me (after a reboot): applications launched from the Dock or from Spotlight inherit environment variables that I set in ~/Library/LaunchAgents/my.startup.plist. (In my case, I needed to set LANG, to en_US.UTF-8, for a Sublime Text plugin.)

comments powered by Disqus