In Leopard, Apple has introduced a new mechanism for managing and maintaining your system path ($PATH).
Previously (and in most current Linux environments) paths were managed by updating the PATH environment variable directly in either the system profile (/etc/profile) or your local profile (~/.bash_profile).
Commonly you had entries like:
export JAVA_HOME = /usr/lib/j2se/jdk1.5.0_13/ export PATH=$PATH:$JAVA_HOME/bin ...
In Leopard, you no longer have to modify the profile to make adjustments to system paths. Instead, you can put a simple text file containing a path entry (or entries) into /etc/paths.d/.
Each line in this file will be interpreted as a path and added automatically to the system path.
macos-gls000120:~ ajordens$ ls -al /etc/paths.d/ total 40 drwxr-xr-x 7 root wheel 238 Jan 22 18:51 . drwxr-xr-x 105 root wheel 3570 Jan 23 11:59 .. -rw-r--r-- 1 root wheel 13 Sep 23 20:53 X11 -rw-r--r-- 1 root wheel 16 Jan 22 18:58 groovy -rw-r--r-- 1 root wheel 15 Jan 22 18:58 maven -rw-r--r-- 1 root wheel 20 Jan 22 18:58 postgresql -rw-r--r-- 1 root wheel 15 Jan 22 18:58 scala macos-gls000120:~ ajordens$ cat /etc/paths.d/scala $SCALA_HOME/bin
It’s up to you whether you include an environment variable or specify the full path.
Enter Leopard
In order to take advantage of this new feature, your /etc/profile needs to invoke /usr/libexec/path_helper. Depending on your upgrade path to Leopard, your profile may or may not have been automatically updated.
Unfortunately mine wasn’t and I couldn’t find a definitive post telling what changes I had to make to the profile. I decided to write the procedure up so that anyone else wanting to take advantage of paths.d and path_helper could do so.
macos-gls000120:~ ajordens$ cat /etc/profile
# System-wide .profile for sh(1)
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
export ANT_OPTS="-Xmx256M"
export POSTGRESQL_HOME="/opt/local/lib/postgresql82"
export CONFBASE=/usr/local/src/confluence-2.6.2
export HADOOP_HOME=/usr/local/src/hadoop-0.15.2
export GROOVY_HOME=/usr/local/src/groovy-1.5.1
export SCALA_HOME=/usr/local/src/scala-2.6.0-final
export MAVEN_HOME=/usr/local/src/maven-2.0.7
export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/"
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
That’s basically it. I put the path_helper invocation at the end of the profile because I wanted to be able to substitute environment variables.
-
Pet Peeve: Don’t email my password to me in plain text You know the drill.
Signup for some random service on the internet
Receive a confirmation email with your account information
or
Forget a password for some random service ...
-
Eclipise Memory Analyzer (MAT) I must say the Eclipse Memory Analyzer looks pretty slick. There is some pretty good material over on the developers blog. Lastly, there was a talk on it ...
-
Open-source Web-based Code Review Tool: Rietveld Guido van Rossum, of Python fame, has recently released a Django-based application that enables web-based code reviews... Rietveld.
It supports any language and currently can hook into Subversion repositories. You ...
-
An implementation of the JVM in Javascript? Caught this over on JavaPosse Google Groups.
Essentially, some bright fellows over in Japan have developed a bytecode->javascript compiler. There's a demo floating around that took a Tetris ...
-
Facebook Chat? So it looks like the Facebook Chat service has finally started rolling out to my network (Facebook Chat has been mentioned previously).
Not quite sure how ...
Latest Entries
- Lessons Learned as a Project Lead
- Good ANTLR Resource
- Testing with Unitils
- Headed to Kelowna for a short vacation (and the laptop stays behind)
- Seam + Groovy + Maven : Nice Simple Hibernate POJOs
- Pet Peeve: Don’t email my password to me in plain text
- Eclipise Memory Analyzer (MAT)
- caBIG Annual Meeting - A developers perspective
- OS X + Java6: java.lang.UnsatisfiedLinkError: /usr/lib/java/libObjCJava.A.dylib
- Getting started with JBoss Seam and Maven
Blogroll
Jan 25th, 2008 at 12:54 am
Interesting tip.
I’d be curious to know if there’s a possibility to easily switch some environment variables. Let’s say today I want to use Java 1.4 and Groovy 1.0, and that later one, working on another project, I want to use Java 5 and Groovy 1.5.
How shall I do?
Feb 28th, 2008 at 3:24 pm
Adam Jordens: The only problem with your solution is that there is little improvement over hardcoded paths in /etc/profile if you hardcode the environment variables instead.
The clean Leopard profile looks like this:
# >>> START
# System-wide .profile for sh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
# <<< END
Similar stuff can be found in csh.login and .zprofile (I can post them if anyone is interested.
Guillaume Laforge: I would make a Java symlink pointing to Java-1.5 somewhere and only add Java/bin to the PATH (so when you switch the symlink you will run new binaries).
Mar 3rd, 2008 at 12:03 am
I agree that it’s not that much of a difference but you will only be hard-coding the paths in one location.
Personally (and prior to using paths.d in Leopard) I’d just do my all my exports and PATH setup in the /etc/profile or .bash_profile directly.
For a lot of frameworks, you will need to define a FRAMEWORK_HOME environment variable in addition to simply including it on the path. In these situations, I’d argue there’s a slight benefit.
And I agree w/ your suggestion to Guillaume, that’s a pretty standard approach to separating your VMs and is something Apple and the various Linux distros having been doing for awhile (/etc/alternatives/java, etc.).
Apr 7th, 2008 at 11:16 am
Thanks for your post! I helped me a lot.
Apr 22nd, 2008 at 4:29 pm
I used a vanilla (unmodified) /etc/profile as it is read only for me, and just added a nice little test file called cdrtools to /etc/paths.d and it worked like a charm! All I had to do was restart my terminal app (opening a new tab would have done the trick as well I assume.
Thanks!
Apr 22nd, 2008 at 4:35 pm
Nevermind that previous comment…like a previous poster mentioned path helper is automatically initialized in the /etc/profile
Jun 24th, 2008 at 12:11 pm
What’s wacky about this whole scheme is that you have no control over load order, so if you (for example) use MacPorts, how do make /opt/local/bin be the first part of your $PATH?
Jul 14th, 2008 at 1:37 pm
Lorin: You can add paths to /etc/paths instead, if you care about the order.
Aug 2nd, 2008 at 12:35 pm
I had also the problem of wanting /usr/local/bin be first in the path before the defaults. My issue was that I wanted to override a default install of svn and use a newer installed in /usr/local/bin. But the problem is the same as for you.
I played around w/ “/etc/path.d” and edited “/etc/paths” itself adding always “/usr/local/bin/” on top but it would always get listed after the defaults.
I looked at “/etc/paths” and found the following entries:
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
I had in “/etc/paths.d/” only the file “X11″ which contained one line: “/usr/X11/bin/”
doing a “set” or “echo $PATH” from the command line would return:
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
So it was clear (also explained in the man page for path_helper) that the content of of the paths.d directory would always be appended to what was found in “paths” itself.
I placed “/usr/local/bin” at top of paths but the order didn’t change. I logged out and back in and even rebooted to make sure there is nothing else causing this behavior but it always remained in the same order.
If I removed “/usr/local/bin” it was gone from the path but the rest stayed as is.
I had the suspicion that the content of “/etc/paths” didn’t really matter for the default entries of “/usr/bin:/bin:/usr/sbin:/sbin” and took them completely out of “/etc/paths” and logged into another shell to prove it. And sure enough, even w/o the entries the path variable was the same.
Therefore here is the order it apparently uses when it calls “path_helper” from /etc/profile at login:
1) System defaults
2) /etc/paths content aside system defaults
3) /etc/paths.d/ content
Apple wanted apparently to play save and not allow users to override system defaults and evtl. cripple the system.
I finally solved the problem by adding
export PATH=/usr/local/bin/:$PATH;
before the path_helper call in /etc/profile:
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
Now “/usr/local/bin” is searched first