72

How do I set a permanent environment variable (i.e. one that does not need exporting every time I start a new Terminal session) in Mac OS X 10.9? I've found a number of answers about modifying my .bash_profile and .profile, however neither of these options seem to work as permanent solutions - only temporary. The variable I'm trying to set is MULE_HOME. I have the following line in my bash profile:

export MULE_HOME=$(/opt/mule-standalone-3.4.0)

However, when I start Terminal I get the following line (not sure if this is normal behaviour?):

-bash: /opt/mule-standalone-3.4.0: is a directory

And running a simple env command returns the following:

TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/fc/68bqp4jj411gynj5qvwhq6z1shs1fy/T/
Apple_PubSub_Socket_Render=/tmp/launch-xKtkql/Render
TERM_PROGRAM_VERSION=326
TERM_SESSION_ID=E97BFE4B-AF85-4933-B252-0883CC085349
USER=dan
SSH_AUTH_SOCK=/tmp/launch-rEmTWW/Listeners
__CF_USER_TEXT_ENCODING=0x730C85DE:0:0
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
__CHECKFIX1436934=1
PWD=/Users/dan
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
LANG=en_GB.UTF-8
MULE_HOME=
SHLVL=1
HOME=/Users/dan
LOGNAME=danwiseman
_=/usr/bin/env

In order to get around this I'm currently having to type export MULE_HOME=/opt/mule-standalone-3.4.0 every time I start a new Terminal session which, whilst not strenuous, is a little inconvenient. What am I doing wrong here that is causing the variable to only be set temporarily?

starball
  • 20,030
  • 7
  • 43
  • 238
danw
  • 1,608
  • 4
  • 29
  • 48

8 Answers8

67

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

touch ~/.bash_profile

then

open -a TextEdit.app ~/.bash_profile

add

export TOMCAT_HOME=/Library/Tomcat/Home

Save document in TextEdit and you are done.

Community
  • 1
  • 1
CodeOverRide
  • 4,431
  • 43
  • 36
43

Drop the $(...) bit, which would attempt to execute the command within the brackets and set $MULE_HOME to whatever it produces. In your case /opt/mule-standalone-3.4.0 is not an executable, hence the error you are getting.

export MULE_HOME=/opt/mule-standalone-3.4.0

and use ~/.bashrc not ~/.bash_profile.

EDIT: It seems opinion is that you should set environment variables in your ~/.bash_profile script, and not ~/.bashrc script.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • 2
    Thanks @trojanfoe, this worked. For reference - what's the reason for using `~/.bashrc` over `~/.bash_profile`? – danw Mar 19 '14 at 10:33
  • 6
    The `.bash_profile` is only executed for a login-shell, whereas `.bashrc` is executed for every new shell instance. – trojanfoe Mar 19 '14 at 10:36
  • And what's the difference between login-shell and shell instance, @trojanfoe ? – fedorqui Mar 19 '14 at 10:48
  • 1
    @fedorqui The term I should probably have used is "interactive" shell, however bash also executes `.bashrc` for login and interactive shells with a line in `.bash_profile`. So I went with "instance". A login shell is only executed when logging in (from another host with `ssh` or via the console) under most unices, however under OSX this is complicated as Terminal.app also runs the shell as a login shell. Therefore under OSX there isn't a lot of difference between the two scripts. – trojanfoe Mar 19 '14 at 10:52
  • 4
    Normally, environment variables go in `.bash_profile`, since they only need to be set once, on login. All descendent processes will inherit the values from their parent. In OS X, `bash` is not used as part of the initial login process, and the `Terminal.app` (or other terminal emulators) process exists outside any pre-existing `bash` sessions, so each new window (by default) treats itself as a new login session. – chepner Mar 19 '14 at 12:27
  • @trojanfoe: `~/.bashrc` is only executed for NON-login shells - thus, since all shells started by `Terminal.app` are login shells - `~/.bashrc` will NOT be read. (By contrast, if you start a interactive, but non-login session by simply typing `bash`, `~/.bashrc` DOES get read). Use `~/.bash_profile`, as @chepner explains. – mklement0 Mar 19 '14 at 13:00
  • @mklement0 Not true; `.bash_profile` typically contains `[ -f ~/.bashrc ] && . ~/.bashrc`. – trojanfoe Mar 19 '14 at 13:01
  • 1
    @trojanfoe: OSX does NOT come with a default ~/.bash_profile, so you cannot RELY on that line being there (as an obvious aside, even if it were there initially, there's no guarantee it will be there later). Using `~/.bash_profile` is the robust choice. The point is that OSX doesn't _automatically_ source `~/.bashrc` for _all_ interactive bash instances, and some OSX users may never use `~/.bashrc` at all. If you still want to recommend its use, please update your answer to explicitly state the prerequisite: the existence of line `[ -f ~/.bashrc ] && . ~/.bashrc` in `~/.bash_profile`. – mklement0 Mar 19 '14 at 13:50
  • Excellent Answer. I came to this website seeking this information and now I have it. Thanks again. – Darth Egregious May 29 '15 at 18:57
13

MacOS 10.15 Catalina and Newer

In case anyone on MacOS 10.15 (Catalina) and up come here, you need to use a .zshenv file instead of .bash_profile. This is because by default since Catalina, the terminal uses zhs instead of bash.

Export paths permanently in the following manner:

  1. Create .zshenv file:

touch ~/.zshenv

  1. Next, open it with the following command:

open -a TextEdit.app ~/.zshenv

  1. Type out the export you want to do in this format:

export NAME=path ex: export PICO_SDK_PATH=/Users/[redacted]/Developer/pico-sdk

Jonathan
  • 511
  • 4
  • 7
4

Alternatively, you can also add the following command to your .bash_profile if you want your environment variables to be visible by graphic applications. In Mac OS X, graphic applications do not inherit your .bash_profile config :

launchctl setenv MYPATH myvar
Jean-Philippe Bond
  • 10,089
  • 3
  • 34
  • 60
4

It seems that Apple keeps changing how to do this. And it's all about context. One way does not necessarily work when another does. I needed it to work in an IDE, and neither of the bash files mention here (Linux style) did that. The current way for GUI apps to respect this on a permanent basis is SUPER convoluted compared to Windows and Linux!

In a nutshell, you have write a huge pile of ugly XML into a plist file to run some bash. That goes into your "launch agents" directory, i.e. ~/Library/LaunchAgents/my.startup.plist. Here's another Stack Exchange thread on the subject:

https://apple.stackexchange.com/questions/106355/setting-the-system-wide-path-environment-variable-in-mavericks

That gives you a full copy & paste which you can tweak to set your specific variable.

BuvinJ
  • 10,221
  • 5
  • 83
  • 96
3

You can put your export statement in ~/.bashrc

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • 6
    On OSX, `~/.bashrc` is NOT executed for *login* shells - which all shells started by `Terminal.app` are; thus, use `~/.bash_profile`. – mklement0 Mar 19 '14 at 12:55
1

I had to run source ~/.bashrc for my changes to show after altering ~/.bashrc, I'm on Big Sur.

Jack Riley
  • 71
  • 1
  • 8
1

In Big Sur in MacOS I think .bashrc is now .zshrc and .bash_profile is now .zprofile.

X T
  • 445
  • 6
  • 22