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:
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
element contains a sequence of
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 "\n"))
(search-forward " ")
(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 " \n")
(insert " " value " \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.