Appify: Wrapping Shell Scripts as Applications in Mac OS X 10.6

Today I'm publishing appify, a shell script that turns any other non-interactive shell script into a double-clickable Mac OS X application bundle. The only magic: Mac OS X will not execute the script if it's smaller than 28 bytes, so appify will balk if your script needs padding.

The Background

For several years now, I have used a series of AppleScripts to automate enabling and disabling of the Mac OS X screen saver password. The scripts were pulled from a thread on the MacWorld forums and have worked well, save for one detail: there is quite a lot of overhead in launching a compiled AppleScript just to execute two commands in the shell:

do shell script "defaults -currentHost write com.apple.screensaver askForPassword -int 0"
do shell script "/Users/adam/bin/notif"

Under heavy load (ie. with all my normal apps, plus VMware Fusion running one or more virtual machines) I often wait 30 seconds or more to enable or disable the password.

Steam was recently ported to Mac OS X, and it has the ability to create application shortcuts on your Desktop. Digging into one of these applications, you see the following hierarchy:

adam@fsck[0]:/Applications:0$ find "Team Fortress 2.app"
Team Fortress 2.app
Team Fortress 2.app/Contents
Team Fortress 2.app/Contents/Info.plist
Team Fortress 2.app/Contents/MacOS
Team Fortress 2.app/Contents/MacOS/run.sh
Team Fortress 2.app/Contents/Resources
Team Fortress 2.app/Contents/Resources/shortcut.icns

Here's Info.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>CFBundleExecutable</key>
        <string>run.sh</string>
        <key>CFBundleIconFile</key>
        <string>shortcut.icns</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>1.0</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>1.0</string>
    </dict>
</plist>

And the good stuff, run.sh:

#!/bin/bash
# autogenerated file - do not edit

open steam://run/440

This was a pretty big "wow" moment for me. No AppleScript, no .command files (which launch Terminal.app), just pure, instant command line gratification. appify was born to quickly convert shell scripts into applications.