2007-11-18 15:24:00
I've always been quite happy about most of the stuff Apple does. A lot of their solutions to problems are elegant and pretty. However, there are also some cases in which they do awful stuff under the hood. Stuff that makes me cringe in disgust.
Case in point, the new path_helper command.
I've been an avid user of LaTexIT, a LaTex helper programme, for a few months now. It's great how easy it makes the creation of mathematical equations in LaTex.
Unfortunately LaTexIT doesn't yet work flawlessly on Leopard. One of the things that goes wrong is the fact that it just won't start :D After trying to start the app a few times, I noticed a run-away process called path_helper.
I asked Pierre whether path_helper might be tied to the problems he's having, because we don't often get run-away processes. Pierre confirmed that others have hinted at path_helper as well, but that he isn't quite sure yet. Unfortunately he doesn't have a Leopard license yet, so he can't debug the problems yet (hint: make a donation if you use LaTexIt! Pierre could use a Leopard license!).
To help him out, I dug around a little bit. What follows is what I e-mailed Pierre. If you don't want to read through the whole bit, here's the summary:
Apple wants to make it easy to expand the $PATH variable for every user on the system automatically. Instead of tagging on new PATH= lines onto the end of /etc/profile, they've created the path_helper command that gets called by /etc/profile. Path_helper reads directory paths from the text files in /etc/paths.d and appends these paths to $PATH.
So because the want to make it just a -little- easier to add to $PATH, they've:
* Created a new directory structure under /etc/paths.d
* Allow new apps or environments to add text files to /etc/paths.d
* Created a new command which simply reads text files and barfs out shell commands.
* Thus broken the Unix standard way of globally setting $PATH.
Good going Apple! You bunch of schmucks!
======================================================
Hmm, this seems to be a weird little, extra tool that Apple has tagged onto the OS. I'm not sure if it's the most elegant solution to the problem. I see what they want to do though: they want to be able to easily make adjustments to the $PATH variable for all users on the system.
Personally I'd just use the global profile in /etc, but apparently Apple have chosen a roundabout way.
Each user's .profile calls that path_helper process. The only thing that path_helper does is generate the requisite sh/csh commands to adjust the $PATH variable.
From the manpage:
=====================
ath_helper(8) BSD System Manager's Manual path_helper(8)
NAME
path_helper -- helper for constructing PATH environment variable
SYNOPSIS
path_helper [-c | -s]
DESCRIPTION
The path_helper utility reads the contents of the files in the directories
/etc/paths.d and /etc/manpaths.d and appends their contents to the PATH and
MANPATH environment variables respectively.
Files in these directories should contain one path element per line.
Prior to reading these directories, default PATH and MANPATH values are
obtained from the files /etc/paths and /etc/manpaths respectively.
Options:
-c Generate C-shell commands on stdout. This is the default if SHELL
ends with "csh".
-s Generate Bourne shell commands on stdout. This is the default if
SHELL does not end with "csh".
NOTE
The path_helper utility should not be invoked directly. It is intended only
for use by the shell profile.
Mac OS X
END
=====================
So instead of putting PATH=$PATH:/usr/whatever/bin in /etc/profile, Apple have decided to make a new config file: /etc/paths.d. This config file will list all directories that need to be appended to the default $PATH.
/me looks at /etc/paths.d
Actually... It's a directory, containing text files with directory paths. For example:
=====================
Kilala:~ thomas$ cd /etc
Kilala:etc thomas$ cd paths.d
Kilala:paths.d thomas$ ls
X11
Kilala:paths.d thomas$ ls -al
total 8
drwxr-xr-x 3 root wheel 102 24 sep 05:53 .
drwxr-xr-x 91 root wheel 3094 13 nov 21:11 ..
-rw-r--r-- 1 root wheel 13 24 sep 05:53 X11
Kilala:paths.d thomas$ file X11
X11: ASCII text
Kilala:paths.d thomas$ cat X11
/usr/X11/bin
=====================
I guess Apple's reasoning is that it's easier to add extra text files to /etc/paths.d, than it is to add a new PATH= line to /etc/profile. Personally, I think it an in-elegant (and rather wasteful) way of doing things :/
Wait, it's even worse! The path_helper gets called from /etc/profile! Ugh! :(
=====================
Kilala:~ thomas$ cd /etc
Kilala:etc thomas$ cat profile
# 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
=====================
Let's see what happens when I run the command...
=====================
Kilala:etc thomas$ /usr/libexec/path_helper -s
PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin"; export PATH
MANPATH="/usr/share/man:/usr/local/share/man:/usr/X11/man"; export MANPATH
=====================
What a totally stupid and annoying way of doing this. What's worse, I'm quite sure it also breaks the Unix-compliancy of Leopard when it comes to standards for setting $PATH.
Hmm :/
kilala.nl tags: apple, meh, sysadmin,
View or add comments (curr. 12)
Posted by jpc (website)
I'm very curious what does breakage of UNIX semantics you have in mind? :)
An for the rationale Apple forgot to add:
They did that because automatic software installation (and what's more important UNinstallation) is much easier this way. Many Linux distros switch to .d directories for many configuration files (Apache 2.0 was AFAIK the first program to support this kind of stuff) because it makes administration much easier.
Posted by Cian
remove the -l flag from the bash call in the source code for LaTeXit and it will work. path_helper is only called by login shells.
Posted by Mark Moorcroft (website)
Any idea how to get path_helper to stick your fink or ports paths AT THE BEGINNING of the PATH variable?
Posted by gert (website)
This is great for automated software installs from .pkg files, MacPorts or Fink. No need for these installers to scan shell startup files for PATHs and adding them. This is a dead easy, cross-shell way of doing it.
I found this page because I was experiencing slow starting zsh login shells. Turned out to be the path_helper script. I think it got confused because I had already set quite a long PATH myself (remnants of an earlier system).
To add fink or MacPorts paths before the defaults are added, I did the following:
Create a /etc/paths.d/000-MacPorts, then move /etc/paths to /etc/paths.d/500-defaults
That should do it.
cheers,
gert
Posted by Thomas
Thanks Gert! You're of course right that path_helper makes things easier on the .PKG creators. However, I still wish there were a more elegant way to achieve the same goal.
Ah well.
Posted by Jason Huebel (website)
I've been bitten by path_helper as well. I wanted /usr/local/bin to be first in the path since I had installed svn 1.5.1 from openCollab. Unfortunately, modifying /etc/paths with /usr/local/bin as the first path doesn't do anything useful. Apparently, path_helper sorts the paths.
Am I missing something? /usr/local/bin and /usr/local/sbin should always be first in the $PATH, IMO. How can I accomplish that in Mac OSX?
Posted by Jason Huebel (website)
Found the answer here:
http://www.softec.st/en/OpenSource/DevelopersCorner/MasteringThePathHelper.html
Since a default path is already set when path_helper is executed, the default path order doesn't change as expected. The link above explains the quick and easy way to make path order behave correctly when calling path_helper.
Posted by Geo Mealer (website)
Really timely advice, Jason. I was here looking for just this solution. With PATH="" in /etc/profile, path_helper actually behaves quite nicely.
I'm guessing this is actually a bug/oversight.
Posted by Chris Johnson (website)
This seems like it might be an interesting avenue for security attacks, too. Imagine installing a package that adds a file to /etc/paths.d. Then later uninstall it. Imagine further that the uninstall does not remove the added path, because in my experience, most uninstalls do not. Now there's a non-existent directory in everybody's path. That seems ripe for exploitation.
Posted by pete
I agree - the Leopard path process gives me the shits, and causes endless compilation problems with new software unless you remember every aspect of it, in order. Damn em!
Good article though!!!
Posted by bulljit
The bug described in http://www.softec.st/en/OpenSource/DevelopersCorner/MasteringThePathHelper.html which required PATH="" in etc/profile appears to be FIXED in Snow Leopard.
path_helper now sets $PATH in the following order:
[ etc/paths ] --> [ etc/paths.d/files ] --> [ $PATH value prior to calling path_helper ]
Therefore moving “/usr/local/bin” to the top in “/etc/paths” now works!
All content, with exception of "borrowed" blogpost images, or unless otherwise indicated, is copyright of Tess Sluijter. The character Kilala the cat-demon is copyright of Rumiko Takahashi and used here without permission.
You are free to use this specific work, to share and distribute it and to adapt it for your own purposes. However, you must attribute this work as mine and you must share all of your alterations. Click on the logo, or follow this link for full details.