rentzsch.com: tales from the red shed

Location-aware .command Files

Unix
Files that end in .command are mapped to Terminal.app in Mac OS X. If their executable flag is set, they are automatically executed. This is a way of putting shell scripts into double-clickable files, and the executable flag requirement helps with the malicious code issue somewhat (but not very much).

The usefulness of these double-clickable files are somewhat limited as it's nonobvious how to get them to act on the contents of the folder they live in. For your pleasure, here's a technique to make the script cd into the folder where it lives, ready to process its neighboring files.

#! /bin/sh
cd `perl -e '$p=$ARGV[0];$p=~s!/[^/]+$!!;print $p;' $0`
pwd

Update: I've also figured out a way for BBEdit worksheets to discover and switch into their enclosing folders:

cd `osascript -e 'tell app "Finder" to POSIX path of ((folder of (file of document 1 of app "BBEdit" as alias)) as string)'`

Funtastic.

Update #2: Malte Tancred told me about dirname, which, given a path, returns the element's parent directory's path. Thus the perl invocation above can be reduced to cd `dirname $0`. Thanks Malte!

Update #3: None other than the famous Randal L. Schwartz, perl writer extraordinaire, wrote me to point out a fatal error in the dirname $0 technique above. It breaks if you have a space in the path! Ugh.

I actually ran into this when Malte mailed me his example, but didn't figure it out. dirname would spit out "usage: dirname path". Malte then mailed me his actual script, which amazingly worked. Turned out my mail download folder's path contains no spaces. Sigh.

Anyway, Randal does more than just point out the error of my ways -- he offers a solution in the form of shell escaping. Here's code that should work:

cd "`dirname \"$0\"`"

Thanks for the help, Randal! Just ignore the entire perl is the spawn of satan thing. (grin) Follow-up to that meeting: I should qualify that link before I get flamed by perl lovers. Turns out Bradley "cheated" and brought a local perl user group leader (whose name I sadly forget right now Alexander Danel -- thanks Bradley!) to take me on. The votes were tied, and it was largely decided that the "debate" was a sham anyway. You should use Perl where it makes sense and other languages where it doesn't.

Update #4: Apparently dirname is an optional install on Mac OS X, part of the BSD subsystem. Thus, there are systems where it won't work. André Pang informs me you can achieve the same effect by using zsch (instead of sh), which always comes with Mac OS X. Here's the equivalent:

#! /bin/zsh
cd "${0:h}"

Wednesday, March 05, 2003
12:00 AM