Custom startup items


In this blog, I've posted several scripts that we run at startup, without being terribly specific as to the details. Today I'd like to remedy that. I'll show you a custom startup item that can run any number of scripts (or executable binaries for that matter) that you place in a special directory.

Over the last couple of years, I've developed several scripts to manage certain aspects of OS X that I run at startup. Originally, I created a custom StartupItem which contained one big script that contained all the code I wanted to run at startup. The main disadvantages of this approach were:

• It wasn't very modular: if I wanted to run some scripts on some machines, and other scripts on other machines, I'd have to maintain different versions of the startup item.

• If you wanted to change the execution order of various subtasks, you needed to rewrite the script.

• All the code needed to be in a single shell language. I could not (easily) mix shell scripts with Perl scripts, and definitely could not (easily) run a pre-compiled binary if needed.

So I rewrote the StartupItem to be a simple shell script that simply ran every executable item in a predefined directory. I could add or remove items in that directory, rename them to control execution order, and can mix and match shell languages.

Let's step through the StartupItem.

A StartupItem is simply a directory (folder) in /Library/StartupItems. I've called mine "FAconfiguration":

[istanbul:/Library/StartupItems/FAconfiguration] madmin% ls -al
total 16
drwxr-xr-x 5 root admin 170 29 Dec 17:16 .
drwxrwxr-x 7 root admin 238 15 Jan 16:11 ..
-rwxr-xr-x 1 root admin 662 29 Dec 17:45 FAconfiguration
drwxr-xr-x 3 root admin 102 29 Dec 17:07 Resources
-rw-r--r-- 1 root admin 181 10 Oct 11:01 StartupParameters.plist

This directory contains three items:
StartupParameters.plist gives the SystemStarter process (which runs the StartupItems) some information about the item:

[istanbul:/Library/StartupItems/FAconfiguration] madmin% cat StartupParameters.plist 
{
    Description     = "Feature Animation Configuration";
    Provides        = ("FA Configuration");
    Requires        = ("Resolver", "Core Services");
    OrderPreference = "Late";
}

"Description" is simply a human-friendly name for the item, and will appear in the startup window that shows what things are being started before the Login Window appears.
"Provides" tells SystemStarter what services your StartupItem provides, this can be important if there are other services that should not be started until AFTER this service is available.
"Requires" tells SystemStarter what services must be available before attempting to run this item. Take a look at the items in /System/Library/StartupItems to get an idea of what is available and required.
"OrderPreference" gives SystemStarter a hint as to where (relatively) in the startup sequence this item should be run. We'd like it to run near the end of the process.

FAconfiguration is the actual script run by SystemStarter. Notice that it has the exact same name as the enclosing directory. SystemStart expects this. Note also that it is executable.

[istanbul:/Library/StartupItems/FAconfiguration] madmin% cat FAconfiguration 
#!/bin/sh

# Master FAconfiguration script
#
# runs each script found in /Library/StartupItems/FAconfiguration/Resources/scripts/

. /etc/rc.common

SCRIPTSDIR="/Library/StartupItems/FAconfiguration/Resources/scripts"
ConsoleMessage "Setting FA configuration"

if [ -d ${SCRIPTSDIR} ]; then
    for script in ${SCRIPTSDIR}/* ; do
        echo ${script}
        if [ -s ${script} -a -x ${script} ]; then
            logger -s -t FAConfiguration -p user.info Executing ${script}... 1>&2

            # run the item
            ${script}

            rc=$?
            if [ $rc -ne 0 ]; then
                logger -s -t FAconfiguration -p user.info ${script} failed with return code ${rc} 1>&2
            fi
        fi
    done
fi

exit 0

You can see that this script simply executes each executable item found in /Library/StartupItems/FAconfiguration/Resources/scripts, and writes some messages to the log to help us debug things if needed.

Finally, the Resources directory simply contains the scripts directory, which in turn contains each of the individual scripts to run:

[istanbul:FAconfiguration/Resources/scripts] madmin% ls -al
total 48
drwxr-xr-x 7 root admin 238 29 Dec 17:57 .
drwxr-xr-x 3 root admin 102 29 Dec 17:07 ..
-rwxr-xr-x 1 root admin 822 29 Dec 17:08 100.PowerManagement
-rwxr-xr-x 1 root admin 1108 29 Dec 17:10 200.SSH
-rwxr-xr-x 1 root admin 324 29 Dec 17:11 300.PasswordMaintenance
-rwxr-xr-x 1 root admin 5183 29 Dec 17:12 400.ValidateSystemUsers
-rwxr-xr-x 1 root admin 3240 31 Dec 10:56 500.setFAautoProxy

In this particular case, the first four scripts are shell scripts, and 500.setFAautoProxy is a Perl script. The scripts are run in "alphabetical" order, so I've named them with starting numbers to make the order obvious.

You can see other blog entries for details on each of the scripts.

Posted: Sat - January 17, 2004 at 05:04 PM      


©