PATH in Yosemite can and should be set within /etc/paths file. Just add your path to the end of this file:
/usr/bin
/bin
/your/custom/path
/etc/environment script in original post provides support for PATH variable in GUI applications (tested with Emacs).
Solution
The solution uses two files: environment.plist
and environment.conf
.
environment.plist
should be placed in ~/Library/LaunchAgents
for a per user solution (recommended), or in /Library/LaunchAgents
for a global solution (not recommended – potential security loophole).
environment.conf
can be placed almost anywhere. $PATH_TO_ENVIRONMENT_CONF
can be relative, but only to the 'default' environment variables, or any that are defined in a EnvironmentVariables
key. 1
environment.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.environment</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>xargs -L 1 launchctl < $PATH_TO_ENVIRONMENT_CONF</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
environment.conf
:
setenv ATOM_HOME $HOME/.config/atom
setenv SOME_VAR "Use quotes if spaces are necessary"
How it works
When a user logs in, the LaunchAgents in ~/Library/LaunchAgents
are executed. In this case, sh -c xargs -L 1 launchctl < $PATH_TO_ENVIRONMENT_CONF
is executed. launchctl
manages daemons and agents. In this case, we are using it to set an environment variable accessible to all applications and the shell.
xargs -L 1 launchctl < $PATH_TO_ENVIRONMENT_CONF
xargs # xargs converts stdin to command line arguments
xargs -L 1 # Tells xargs to invoke launchctl for each line
launchctl # Run launchctl with the arguments
< # Since a plist is an xml document, angle brackets must be escaped.
< $PATH_TO_ENVIRONMENT_CONF
# This tells xargs to read input from the file at $PATH_TO_ENVIRONMENT_CONF
This solution can also be extended to other launchctl subcommands.
Best Answer
export ENV_VAR="/Applications/Android Studio.app"
should set the variable properly, but it's likely the program/script that uses the variable doesn't quote it properly. If if you can figure out what's using the variable, it might be possible to fix the script/program.My first guess would be that the environment variable is used by a shell script that does something like:
The problem occurs because the shell will expand the variable, then perform word splitting -- that is, it will split
/Applications/Android Studio.app/subdir/filename
into two arguments:/Applications/Android
andStudio.app/subdir/filename
. Note that embedding escapes or quotes in the variable value doesn't do anything useful, because the shell processes quotes and escapes before performing variable substitutions. Thus, if you usedexport ENV_VAR="/Applications/Android\ Studio.app"
, it would be split into/Applications/Android\
andStudio.app/subdir/filename
; if you usedexport ENV_VAR="'/Applications/Android Studio.app'"
it would be split into'/Applications/Android
andStudio.app/subdir/filename'
.The solution is to put double-quotes around the variable reference, like this:
which tells the shell not to perform word splitting after substitution, removing the problem.
Note that it's also possible that it's something other than a shell script, or a shell script that's doing something more complicated like using the variable to construct another variable, and possibly depending on word splitting when that variable is used. Fixing this sort of usage can get messy.