Setting environment variables on OS X - macos

What is the proper way to modify environment variables like PATH in OS X?
I've looked on Google a little bit and found three 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 OS X uses bash now. Where are these variables, especially PATH, defined?
I'm running OS X v10.5 (Leopard).

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.
Please note that environment.plist does not work for applications launched via Spotlight. This is documented by Steve Sexton here.
Open a terminal prompt
Type sudo vi /etc/launchd.conf (note: this file might not yet exist)
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
Save your changes in vi and reboot your Mac. Or use the grep/xargs command which is shown in the code comment above.
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 IDEA and other GUI applications you launch via Spotlight.

Don't expect ~/.launchd.conf to work
The man page for launchctl says that it never worked:
DEPRECATED AND REMOVED FUNCTIONALITY
launchctl no longer has an interactive mode, nor does it accept commands from stdin. The /etc/launchd.conf file is no longer consulted for subcommands to run during early boot time; this functionality was removed for security considerations. While it was documented that $HOME/.launchd.conf would be consulted prior to setting up a user's session, this functionality was never implemented.
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:
PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
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 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:$PATH for bash or zsh.
How to keeping changes after a reboot
New method (since 10.10 Yosemite)
Use launchctl config user path /bin:/usr/bin:/mystuff. See man launchctl for more information.
Previous method
The launchctl man page quote at the top of this answer says the feature described here (reading /etc/launchd.conf at boot) was removed for security reasons, so ymmv.
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 launchd.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.

Up to and including OS X v10.7 (Lion) you can set them in:
~/.MacOSX/environment.plist
See:
https://developer.apple.com/legacy/library/qa/qa1067/_index.html
https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/EnvironmentVars.html
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 OS X v10.8 (Mountain Lion) and beyond you need to use launchd and launchctl.

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))
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" "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 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 ~/.osx-env-sync.sh with the following contents:
grep export $HOME/.bash_profile | while IFS=' =' read ignoreexport envvar ignorevalue; do
launchctl setenv "${envvar}" "${!envvar}"
done
Make sure the shell script is executable:
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.
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 Terminal.app) 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).

Do:
vim ~/.bash_profile
The file may not exist (if not, you can just create it).
Type in this and save the file:
export PATH=$PATH:YOUR_PATH_HERE
Run
source ~/.bash_profile

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, ensure 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.
Details:
Login item: ~/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
;;; 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_profile content platform independent and put the setting of the launchd environment (a Mac only facility) into a separate script.

Another, free, opensource, Mac OS X v10.8 (Mountain Lion) 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.
<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.
Disclaimer: I am in no way related to the developer or his/her project.
P.S. I like the name (sounds like 'Ends Pain').

On Mountain Lion all the /etc/paths and /etc/launchd.conf editing doesn't make 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 application's Info.plist (right click on "AppName.app" (in this case SourceTree) and then "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)
Now the application (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.

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

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.

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 IDEA 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 OS X the applications are not started as in other Unix'es; they don't inherit the parent's shell variables. All the other modifications won't work for a reason that is unknown to me. Maybe someone else can clarify about this.

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)

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.

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:
Add to the PATH on Mac OS X 10.8 Mountain Lion and up

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:
My .bash_profile consists solely of one line, (This is just personal preference.)
source .bashrc
My .bashrc has this:
function export()
{
builtin export "$#"
if [[ ${##} -eq 1 && "${#//[^=]/}" ]]
then
launchctl setenv "${#%%=*}" "${##*=}"
elif [[ ! "${#//[^ ]/}" ]]
then
launchctl setenv "${#}" "${!#}"
fi
}
export -f export
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
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
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.
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.

I think the OP is looking for a simple, Windows-like solution.
Here you go:
http://www.apple.com/downloads/macosx/system_disk_utilities/environmentvariablepreferencepane.html

Feb 2022 (MacOs 12+)
Solutions here should work after reboot or application restart.
CLI
Open your CLI of choice config file.
For bash open ~/.bash_profile
For zsh open ~/.zshrc
add (or replace)
export varName=varValue
(if varValue has spaces in it - wrap it in ")
Make sure to restart command line app.
GUI
Complete the CLI step.
Make sure GUI app is closed.
Open GUI app from the command line. For example:
open /Applications/Sourcetree.app
(you can also alias this command in the .zshrc)
Principles
Mac does not have a configuration options that sets environment variable for all contexts.
Avoid changing anything outside your user profile.
Doesn't work anymore
launchctl config user varName varVal (MacOS 12.1+)
Editing /etc/launchd.conf
xml file with plist suffix

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

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 in PATH and other environment issues in Leopard (2008-11)

/etc/launchd.conf is not used in OS X v10.10 (Yosemite), OS X v10.11 (El Capitan), macOS v10.12 (Sierra), or macOS v10.13 (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.)

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 documement and you are done.

All the magic on iOS only goes with using source with the file, where you export your environment variables.
For example:
You can create an file like this:
export bim=fooo
export bom=bar
Save this file as bimbom.env, and do source ./bimbom.ev.
Voilá, you got your environment variables.
Check them with:
echo $bim

It's simple:
Edit ~/.profile and put your variables as follow
$ vim ~/.profile
In file put:
MY_ENV_VAR=value
Save ( :wq )
Restart the terminal (Quit and open it again)
Make sure that`s all be fine:
$ echo $MY_ENV_VAR
$ value

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 the /etc/paths and ~/.MacOSX/environment.plist files. 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.
I don't know how often this is with Mac OS X. I think the distinction has broken down with the window system launching everything.
Personally, I eliminate the confusion by creating a .bashrc file with everything I need and then do:
ln -s .bashrc .bash_profile

One thing to note in addition to the approaches suggested is that, in OS X 10.5 (Leopard) 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.

Set up your PATH environment variable on Mac OS
Open the Terminal program (this is in your Applications/Utilities 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 every time you open the Terminal program your PATH will include the Android SDK.

It's quite simple. Edit file .profile (vi, nano, Sublime Text or other text editor) file. You can found it at the ~/ directory (user directory) and set like this:
export MY_VAR=[your value here]
Example with Java home:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/current
Save it and return to the terminal.
You can reload it with:
source .profile
Or close and open your terminal window.

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.
It's important to understand here that with Bash, file .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, let’s 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 methods in there.
.bash_profile: create if non-existing. Put the following in there.
.bash_file:
#!/bin/bash
source ~/.profile # Get the PATH settings
source ~/.bashrc # Get Aliases and Functions
#

Login Shells
/etc/profile
The shell first executes the commands in file /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.

Related

How to update PATH to find nvcc for CUDA 8.0? [duplicate]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
On Linux, how can I add a directory to the $PATH so it remains persistent across different sessions?
Background
I'm trying to add a directory to my path so it will always be in my Linux path. I've tried:
export PATH=$PATH:/path/to/dir
This works, however each time I exit the terminal and start a new terminal instance, this path is lost, and I need to run the export command again.
How can I do it so this will be set permanently?
You need to add it to your ~/.profile or ~/.bashrc file.
export PATH="$PATH:/path/to/dir"
Depending on what you're doing, you also may want to symlink to binaries:
cd /usr/bin
sudo ln -s /path/to/binary binary-name
Note that this will not automatically update your path for the remainder of the session. To do this, you should run:
source ~/.profile
or
source ~/.bashrc
There are multiple ways to do it. The actual solution depends on the purpose.
The variable values are usually stored in either a list of assignments or a shell script that is run at the start of the system or user session. In case of the shell script you must use a specific shell syntax and export or set commands.
System wide
/etc/environment List of unique assignments. Allows references. Perfect for adding system-wide directories like /usr/local/something/bin to PATH variable or defining JAVA_HOME. Used by PAM and systemd.
/etc/environment.d/*.conf List of unique assignments. Allows references. Perfect for adding system-wide directories like /usr/local/something/bin to PATH variable or defining JAVA_HOME. The configuration can be split into multiple files, usually one per each tool (Java, Go, and Node.js). Used by systemd that by design do not pass those values to user login shells.
/etc/xprofile Shell script executed while starting X Window System session. This is run for every user that logs into X Window System. It is a good choice for PATH entries that are valid for every user like /usr/local/something/bin. The file is included by other script so use POSIX shell syntax not the syntax of your user shell.
/etc/profile and /etc/profile.d/* Shell script. This is a good choice for shell-only systems. Those files are read only by shells in login mode.
/etc/<shell>.<shell>rc. Shell script. This is a poor choice because it is single shell specific. Used in non-login mode.
User session
~/.pam_environment. List of unique assignments, no references allowed. Loaded by PAM at the start of every user session irrelevant if it is an X Window System session or shell. You cannot reference other variables including HOME or PATH so it has limited use. Used by PAM.
~/.xprofile Shell script. This is executed when the user logs into X Window System system. The variables defined here are visible to every X application. Perfect choice for extending PATH with values such as ~/bin or ~/go/bin or defining user specific GOPATH or NPM_HOME. The file is included by other script so use POSIX shell syntax not the syntax of your user shell. Your graphical text editor or IDE started by shortcut will see those values.
~/.profile, ~/.<shell>_profile, ~/.<shell>_login Shell script. It will be visible only for programs started from terminal or terminal emulator. It is a good choice for shell-only systems. Used by shells in login mode.
~/.<shell>rc. Shell script. This is a poor choice because it is single shell specific. Used by shells in non-login mode.
Notes
GNOME on Wayland starts a user login shell to get the environment. It effectively uses the login shell configurations ~/.profile, ~/.<shell>_profile, ~/.<shell>_login files.
Man pages
environment
environment.d https://linux.die.net/man/1/environment.d
bash
dash
Distribution-specific documentation
Ubuntu
Arch Linux
Related
Difference between Login Shell and Non-Login Shell?
In Ubuntu, edit /etc/environment. Its sole purpose is to store environment variables. Originally the $PATH variable is defined here.
This is a paste from my /etc/environment file:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
So you can just open up this file as root and add whatever you want.
For immediate results,
Run (try as normal user and root):
source /etc/environment && export PATH
If you use Z shell (zsh), add this line right after the comments in /etc/zsh/zshenv file:
source /etc/environment
I encountered this little quirk on Ubuntu 15.10 (Wily Werewolf), but if your zsh is not getting the correct PATH, this could be why.
For Bash, you can put the export declaration in ~/.bashrc. For example, my .bashrc contains this line:
export PATH=/var/lib/gems/1.8/bin:/home/ash/.bin:$PATH
You may set $PATH permanently in two ways.
To set the path for a particular user:
You may need to make the entry in file .bash_profile in the home directory for the user.
E.g, in my case I will set the java path in the Tomcat user profile*
echo "export PATH=$PATH:/path/to/dir" >> /home/tomcat/.bash_profile
To set a common path for all system users, you may need to set the path like this:
echo "export PATH=$PATH:/path/to/dir" >> /etc/profile
You can use on CentOS or Red Hat Linux (RHEL) for the local user:
echo $"export PATH=\$PATH:$(pwd)" >> ~/.bash_profile
This adds the current directory (or you can use another directory) to the PATH. This makes it permanent, but it takes effect at the next user logon.
If you don't want do a re-logon, then you can use:
source ~/.bash_profile
That reloads the # User specific environment and startup programs. This comment is present in file .bash_profile.
You can also set it permanently, editing one of these files:
/etc/profile (for all users)
~/.bash_profile (for current user)
~/.bash_login (for current user)
~/.profile (for current user)
You can also use /etc/environment to set a permanent PATH environment variable, but it does not support variable expansion.
Extracted from: Linux: Añadir ruta al PATH
I think the most elegant way is:
Add this in the ~/.bashrc file.
Run this command:
gedit ~/.bashrc
Add your path inside it:
export PATH=$PATH:/opt/node/bin
source ~/.bashrc
(Ubuntu)
Modify the "/etc/profile" file:
vi /etc/profile
Press the I key to enter editing mode and move the cursor to the end of the file. Additional entries:
export PATH=$PATH:/path/to/dir;
Press the Esc key to exit edit mode, and :wq to save the file.
Make the configuration effective
source /etc/profile
Explanation:
The profile file works for all users. If you want it to be valid only for the active user, change the ".bashrc" file.
I stumbled across this question yesterday when searching for a way to add a folder containing my own scripts to the PATH - and was surprised to find out that my own ~/.profile file (on Linux Mint 18.1) already contained this:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
Thus, all I had to do was create the folder ~/bin and put my scripts there.
You can add that line to your console configuration files (e.g., .bashrc, or to .profile).
After so much research, I found a simple solution for this (I am using Elementary OS), inspired by Flutter – Step by Step Installation on Linux – Ubuntu.
Run the following command to open the .bashrc file in edit mode. (You
may also use vi or any other editor).
~$ sudo nano ~/.bashrc
Add the following line at the end of the file and save.
export PATH="[FLUTTER_SDK_PATH]/flutter/bin:$PATH"
For example:
export PATH="/home/rageshl/dev/flutter/bin:$PATH"
I believe this is the permanent solution for setting the path in Flutter in a Ubuntu distribution.
It can be directly added by using the following command:
echo 'export PATH=$PATH:/new/directory' >> ~/.zshrc
source ~/.zshrc
One way to add a permanent path, which worked for me, is:
cd /etc/profile.d
touch custom.sh
vi custom.sh
export PATH=$PATH:/path according to your setting/
Restart your computer and here we go; the path will be there permanently.
Add script file [name_of_script].sh to the /etc/profile.d folder with the line:
export PATH=$PATH:/dir
Every script within the /etc/profile.d folder is automatically executed by /etc/profile on login.
My answer is in reference to the setting up of a Go environment on Ubuntu Linux (amd64). I have faced the same trouble of setting the path of environment variables (GOPATH and GOBIN), losing it on terminal exit and rebuilding it using the source <file_name> every time.
The mistake was to put the path (GOPATH and GOBIN) in ~/.bash_profile file. After wasting a few good hours, I found that the solution was to put GOPATH and GOBIN in the ~/.bash_rc file in the manner:
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOPATH:$GOBIN
And in doing so, the Go installation worked fine and there were no path losses.
The reason with which this issue can be related is that settings for non-login shells, like your Ubuntu terminal or GNOME terminal where we run the Go code, are taken from the ~./bash_rc file and the settings for login shells are taken from ~/.bash_profile file. And from the ~/.profile file if the ~/.bash_profile file is unreachable.
The files where you add the export command depends on if you are in login-mode or non-login-mode.
If you are in login-mode, the files you are looking for are either /etc/bash or /etc/bash.bashrc.
If you are in non-login-mode, you are looking for the file /.profile or for the files within the directory /.profiles.d
The files mentioned above is where the system variables are.
Permanently add to the PATH variable
Global:
echo "export PATH=$PATH:/new/path/variable" >> /etc/profile
Local (for the current user only):
echo "export PATH=$PATH:/new/path/variable" >> ~/.profile
For global, restart. For local, relogin.
Example
Before:
$ cat /etc/profile
#!/bin/sh
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
After:
$ cat /etc/profile
#!/bin/sh
export PATH=/usr/bin:/usr/sbin:/bin:/sbin
export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/new/path/variable
Alternatively you can just edit file "profile":
$ cat /etc/profile
#!/bin/sh
export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/new/path/variable
Another way (thanks gniourf_gniourf):
echo 'PATH=$PATH:/new/path/variable' >> /etc/profile
You shouldn't use double quotes here! echo 'export
PATH=$PATH:/new/path/variable'... And by the way, the export keyword
is very likely useless as the PATH variable is very likely already
marked as exported. – gniourf_gniourf
Zues77 has the right idea. The OP didn't say "How can I hack my way through this?". The OP wanted to know how to permanently append to $PATH:
sudo nano /etc/profile
This is where it is set for everything and is the best place to change it for all things needing $PATH.
Let's say you're running macOS. You have a binary you trust and would like to make available across your system, but don't necessarily want the directory in which the binary is to be added to your PATH.
You can opt to copy/move the binary to /usr/local/bin, which should already be in your PATH. This will make the binary executable like any other binary you may already have access to in your terminal.
The simplest way is the following line,
PATH="<directory you want to include>:$PATH"
in your .bashrc file in the home directory.
It will not get reset even if you close the terminal or reboot your PC. It's permanent.
This is a one-liner. It adds a line to the .bashrc. That line is going to check if the directory has already been added to the path and append if not. This will prevent duplicating your directory in the path every time you source .bashrc.
echo "[[ \":\$PATH:\" != *\":$(pwd)/path/to/add:\"* ]] && export PATH=\"\${PATH:+\${PATH}}:$(pwd)/path/to/add\"" >> ~/.bashrc
source ~/.bashrc
I think the most elegant way is:
Add this in the ~./bashrc file:
if [ -d "new-path" ]; then
PATH=$PATH:new-path
fi
source *~/.bashrc*
(Ubuntu)
For a Debian distribution, you have to:
edit file ~/.bashrc. E.g: vim ~/.bashrc
add export PATH=$PATH:/path/to/dir
then restart your computer. Be aware that if you edit file ~/.bashrc as root, your environment variable you added will work only for root

Setting environment variables in Yosemite

What is the proper way to modify environment variables like PATH in Yosemite?
This is this question Setting environment variables in OS X? but specifically for yosemite since it doesn't work anymore.
Have you tried editing ~/.bash_profile?
Adding a line like this to bash_profile ought to do it:
export PATH=/usr/local/bin:$PATH
What shell are you using? I'm assuming you're using the default Bash shell. There's also Csh, Ksh, and Zsh.
The Terminal.app on Mac OS X by default starts a new login shell each time a window is open. This means that $HOME/.bash_profile or $HOME/profile is always executed when you open a new terminal window. You can set particular defaults in here. For example, I set PS1 and set -o vi.
NOTE: This may not be the case if you're using other Terminal apps like xterm. These open new terminal windows as just new shells. This means that you may not see the changes made in .bash_profile until you log out and log back in.
You can try editing $HOME/.bashrc and see if that helps.
What about other shells?
If you're using Kornshell (ksh), you need to edit the $HOME/profile and not $HOME/.bash_profile. If you're using Zshell (zsh), you're on your own. It's too wacky to describe here. Read the manpage for zsh and search for ZDOTDIR.
When you run a shell script, the $HOME/.bashrc is executed. Most people put something like this in their .bash_profile, so their .bashrc settings are included in a new terminal window:
[[ -x $HOME/.bashrc ]] && source "$HOME/.bashrc"
Some people set things they want to be set when they run a shell script, for example export $PS4="\$LINENO> ".
The $PATH is a bit different. You can set it in .bash_profile (I would not set it in .bashrc), But, Mac OS X has an automated why on how systemwide paths are set. A file called /etc/paths is used to set the default path for all users using either Bash or Kornshell via the /usr/libexec/path_helper program.
On my Mac, I set my $PATH to:
/usr/local/bin:/usr/share/bin:/bin:/usr/bin:/usr/sbin:/sbin:$HOME/bin
When I install programs, I usually install them under /opt when possible. Then, I link their binaries (where ever they're placed) to /usr/local/bin. This way, I don't have to keep building my PATH. Plus, it allows me to override system defaults. For example, /usr/bin/git is at 1.9.3. while my installed /usr/local/bin/git is at version 2.2.1.
One thing you should not do is modify /etc/profile because changes there may be replaced on OS X upgrades.
The problem is not with environment variables set and accessed from within /bin/bash or /bin/sh, but with envars that should be set for programs NOT executed from the shell; i.e. normal apps executed from the dock or Finder.
After finally getting things right with launchctl in Mavericks, Apple is in the process of changing things again. The useful subcommands of launchctl are now labelled as "legacy subcommands", some of which are no longer supported. That leaves a question mark over the others.
In any case, the most important subcommands are still available for now.
launchctl allows for the setting of the overall environment in which user processes execute. It appears that the overall user environment is inherited by all Terminal processes; i.e. all setenv variables are exported. It's a bit tricky to confirm that. In any case, you will still need your .profile and .bashrc to define functions and aliases, which are not supported by launchctl.
I go to some lengths to ensure that all of my launchctl vars are also defined in my profile. This enables me to set up the same environment on remote or VM linux systems, with a few minor tweaks.
Al of my setup is described in this blog post .
following solution worked for me.
Open Terminal
Click on Terminal Menu at right upper corner.
click on Preferences
Click on General
Change Shell open with to command and put /bin/bash in text box.
Now whatever configuration you do in ~/.bash_profile takes effect. Previously you were not using bash(were using ksh) that is why it was not reading .bash_profile.

Why do my TextMate bundles sometimes not have access to environment/shell variables?

I have a TextMate bundle written in ruby that accesses the ENV hash to read shell variables.
It sometimes succeeds in reading this variable, and sometimes doesn't find it. I've been unable to figure out the pattern.
What dictates which shell variables will be visible to a TextMate bundle?
update
ah ha! When I launch TextMate from the command line, it works. If I launch it from the dock, it does not work (even if I then subsequently open a directory from the command line).
So the question now is, why does TextMate choose to pick up different environments in these cases, and is there a way to make them identical?
Textmate is launched via launchd, not from the shell.
Your $PATH will travel over if you run something directly from the shell (open -a Textmate does not work, open will not pass your environment to Textmate).
The ways to get around this are environment.plist, launchctl, or launchd.conf:
Setting environment variables in OS X?
update
If you edit /etc/launchd.conf and reboot, the changes will take effect. Each line can be a launchctl command like setenv VAR_NAME "VAR_VALUE". You could then run this file with launchctl your_file.
It's a pain having to reboot though. And if you want per-user environment settings, this is no good. Apple proposes ~/.launchd.conf could be used for user-specific settings, but has yet to implement this feature.
You could set a script to run on login with a LoginHook and LogoffHook (see Apple's documentation). Or, using LaunchAgents. For detailed directions on how to set up a LaunchAgent, look at nicksay's post on this Macworld post.
The launchctl setenv command doesn't seem to work while logged in. I'm currently banging my head against this.
I ran into basically the same problem you're having today (the Makefile bundle would not pass LIBRARY_PATH to gcc), and now I'm writing a python script that will read a file of variable assignments on login, store a copy of the current environment and that file with the assignments, and then unload all the variables on logout. That also reminds me, I should have an update option. I'll post a comment with the link to a github repo for it here when I'm done. If it works, that is.

Environment variables in Mac OS X

Update: The link below does not have a complete answer. Having to set the path or variable in two places (one for GUI and one for shell) is lame.
Not Duplicate of: Setting environment variables in OS X?
Coming from a Windows background where it's very easy to set and modify environment variables (just go to System Properties > Advanced > Environment Variables), it does not seem to be that straight forward on Mac OS 10.5. Most references say I should update /etc/profile or ~/.profile. Are those the equivalent of System Variables and User Variables? For example, where should I set my JAVA_HOME variable?
EDIT:
I want to be able to access the variable from the terminal as well as an app like Eclipse. Also, I hope I don't have to restart/logout to make this take effect.
There are several places where you can set environment variables.
~/.profile: use this for variables you want to set in all programs launched from the terminal (note that, unlike on Linux, all shells opened in Terminal.app are login shells).
~/.bashrc: this is invoked for shells which are not login shells. Use this for aliases and other things which need to be redefined in subshells, not for environment variables that are inherited.
/etc/profile: this is loaded before ~/.profile, but is otherwise equivalent. Use it when you want the variable to apply to terminal programs launched by all users on the machine (assuming they use bash).
~/.MacOSX/environment.plist: this is read by loginwindow on login. It applies to all applications, including GUI ones, except those launched by Spotlight in 10.5 (not 10.6). It requires you to logout and login again for changes to take effect. This file is no longer supported as of OS X 10.8.
your user's launchd instance: this applies to all programs launched by the user, GUI and CLI. You can apply changes at any time by using the setenv command in launchctl. In theory, you should be able to put setenv commands in ~/.launchd.conf, and launchd would read them automatically when the user logs in, but in practice support for this file was never implemented. Instead, you can use another mechanism to execute a script at login, and have that script call launchctl to set up the launchd environment.
/etc/launchd.conf: this is read by launchd when the system starts up and when a user logs in. They affect every single process on the system, because launchd is the root process. To apply changes to the running root launchd you can pipe the commands into sudo launchctl.
The fundamental things to understand are:
environment variables are inherited by a process's children at the time they are forked.
the root process is a launchd instance, and there is also a separate launchd instance per user session.
launchd allows you to change its current environment variables using launchctl; the updated variables are then inherited by all new processes it forks from then on.
Example of setting an environment variable with launchd:
echo setenv REPLACE_WITH_VAR REPLACE_WITH_VALUE | launchctl
Now, launch your GUI app that uses the variable, and voila!
To work around the fact that ~/.launchd.conf does not work, you can put the following script in ~/Library/LaunchAgents/local.launchd.conf.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>local.launchd.conf</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>launchctl < ~/.launchd.conf</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Then you can put setenv REPLACE_WITH_VAR REPLACE_WITH_VALUE inside ~/.launchd.conf, and it will be executed at each login.
Note that, when piping a command list into launchctl in this fashion, you will not be able to set environment variables with values containing spaces. If you need to do so, you can call launchctl as follows: launchctl setenv MYVARIABLE "QUOTE THE STRING".
Also, note that other programs that run at login may execute before the launchagent, and thus may not see the environment variables it sets.
There's no need for duplication. You can set environment variables used by launchd (and child processes, i.e. anything you start from Spotlight) using launchctl setenv.
For example, if you want to mirror your current path in launchd after setting it up in .bashrc or wherever:
PATH=whatever:you:want
launchctl setenv PATH $PATH
Environment variables are not automatically updated in running applications. You will need to relaunch applications to get the updated environment variables (although you can just set variables in your shell, e.g. PATH=whatever:you:want; there's no need to relaunch the terminal).
I think what the OP is looking for is a simple, windows-like solution.
here ya go:
https://www.macupdate.com/app/mac/14617/rcenvironment
You can read up on linux, which is pretty close to what Mac OS X is. Or you can read up on BSD Unix, which is a little closer. For the most part, the differences between Linux and BSD don't amount to much.
/etc/profile are system environment variables.
~/.profile are user-specific environment variables.
"where should I set my JAVA_HOME variable?"
Do you have multiple users? Do they care? Would you mess some other user up by changing a /etc/profile?
Generally, I prefer not to mess with system-wide settings even though I'm the only user. I prefer to edit my local settings.
For GUI apps, you'll have to create and edit ~/.MacOSX/environment.plist. More details here. You will need to log out for these to take effect. I'm not sure if they also affect applications launched from Terminal, but I assume they would.
For apps launched from Terminal, you can also edit the ~/.profile file.
Synchronize OS X environment variables for command line and GUI applications from a single source with osx-env-sync.
I also posted an answer to a related question here.
Just open the ~/.profile file, via nano in Terminal and type there :
export PATH=whatever/you/want:$PATH
Save this file (cmd+X and Y).
After that please logout/login again or just open a new tab in Terminal and try use your new variable.
PLEASE DON'T forget to add ":$PATH" after whatever/you/want, otherwise you'll erase all paths in PATH variable, which were there before that.
I wrote a tool to make it easy to manage the environment variables for macOS applications.
https://github.com/yuezk/macenv
You can set the environment variable with macenv set, for example:
macenv set JAVA_HOME /path/to/java/home
Under the hood, it calls launchctl setenv to set the environment variables, saves the environment variables to ~/.launchd.conf at the same time, and registers an auto-start service to load the environment variables when the OS restarts.
If you want to change environment variables permanently on macOS, set them in /etc/paths. Note, this file is read-only by default, so you'll have to chmod for write permissions.
For 2020 Mac OS X Catalina users:
Forget about other useless answers, here only two steps needed:
Create a file with the naming convention: priority-appname. Then copy-paste the path you want to add to PATH.
E.g. 80-vscode with content /Applications/Visual Studio Code.app/Contents/Resources/app/bin/ in my case.
Move that file to /etc/paths.d/. Don't forget to open a new tab(new session) in the Terminal and type echo $PATH to check that your path is added!
Notice: this method only appends your path to PATH.

How to set the $PATH as used by applications in os x

I'm using ant to build my project, and use the 'svnversion' executable to insert a version id into my sources for easy tracking of versions.
Running this ant file from the command line works, I've set my $PATH in .profile to include the path to svnversion and it works fine.
Now I try and run this same ant file from inside Eclipse and that does not work - the PATH in eclipse is set in another way than the PATH of the shell, I suspect this has to be set in a plist somewhere, but I don't know where.
Correct -- it's in the plist file
~/.MacOSX/environment.plist
This file actually contains key-value pairs for any environment variables you want to set, for the whole login session. Unlike .profile/.cshrc etc, it's available to GUI programs. Unfortunately, you can't access other environment variables (e.g., you can't use $HOME) or use any other programmatic constructs here.
Update: note that this is no longer supported under OS X 10.8 Mountain Lion, alas.
A quick search at developer.apple.com turned up Setting environment variables for user processes.
On Mac OS X El Capitan (10.11.5), this works for me for per-user PATH entries (and other environment variables, for that matter).
create a file $HOME/.profile
set all PATH related variables in that file
(if using bash), have your .bash_profile source that file, and .bashrc. This should be the entire contents of your .bash_profile:
# $HOME.bash_profile:
source $HOME/.profile
source $HOME/.bashrc
Near as I can tell, Mac OS does not source .bash_profile on login for PATH, presumably because that is often very slow to run (initializing bash completion etc). It does seem to read $HOME/.profile.
You still need a $HOME/.bash_profile to trigger bash to read $HOME/.bashrc, which it otherwise wouldn't do for interactive, non-login terminals as the ones created by Terminal.app.

Resources