One of Tiger’s unsung additions is a new Unix utility, launchd, that can automatically run anything—including applications, AppleScripts, shell scripts, and Automator workflows. Use it to launch a program at startup or login, on a fixed or repeating schedule, when a file changes, or when you add a new file to a folder. It can even start a program in response to network access on a certain port.
Launchd improves system performance by limiting the number of background processes that must run all the time. It also makes automation easier; this single tool replaces numerous launch utilities, including cron, rc, and watchdog. I’ll walk you through the process of creating two example launchd jobs: a simple daily backup, and a job that moves files from your Drop Box folder to your desktop. If you get hooked, you can learn more about launchd here.
Get ready for takeoff
To create a launchd job, you create a preference (.plist) file listing what you want to launch, as well as when and how. Then you put the file in one of several folders. The folder you choose determines when the job loads and whether it runs as the root user or as another user.
When you’re creating the job, save yourself some grief by using Peter Borg’s free Lingon. This utility writes the XML code and gives you an easy way to perform steps that would otherwise require a trip to Terminal.
When you open Lingon, you’ll see five tabs across the program window. These represent the different folders where you can store launchd jobs.
My Agents The jobs listed in this pane live in / your user folder /Library/LaunchAgents. They load when you log in. Use this location for any job that should affect only files within your user folder, or that should run only when you’re logged in.
Users Agents Jobs listed in this pane are stored in /Library/LaunchAgents. They load when any user logs in, and run as that user. This would be useful when you want a background program to run for all a machine’s users but don’t want to put it in each user’s Login Items list.
Users Daemons Jobs listed in this pane reside in /Library/LaunchDaemons. They load when your Mac starts up and they run as the root user. This is useful for jobs that need to run regardless of which user (if any) is logged in, or for jobs that perform actions requiring an administrator password.
System Agents and System Daemons Jobs listed here are stored in /System/Library/LaunchAgents and /System/Library/LaunchDaemons, respectively. Like jobs in the Users Daemons pane, they load at startup and run as the root user, but because they’re inside the System folder, you should not modify them. You may, however, find it instructive to look at the System Daemons list, which contains all of Tiger’s preinstalled launchd jobs. Many of these formerly used cron. ( Click here for more about cron.)
Create a backup job
Say you want to create a job that backs up a Mac’s Users folder every day. You could use Automator and iCal, but the workflow would skip files not owned by the user currently logged in. Using launchd, you can copy data for all users at the same time and schedule the backup to occur no matter which user (if any) is logged in.
To begin, open Lingon. Click on the New button in the toolbar and select Users Daemons in the sheet that appears. Click on Create, and then enter your administrator password. You’ll enter the rest of your settings in the sheet that appears.
Name That Job Click on the Basic tab and enter a name in the Label field. This name must be unique on this computer or the job won’t load. Apple recommends this naming pattern: com.macworld.DailyBackup. The first two parts of the name should look like a backward domain name. (You can use your actual domain name, make one up, or use com.your_short_user_name; this convention simply makes sure that two people don’t come up with the same name.) Lingon automatically adds the .plist extension when it saves the file.
Pick Your Target Click on the plus-sign (+) button next to the ProgramArguments field and enter the full path for the program you want to launch. In this example, you’re going to run a Unix command. These often use flags to set options and arguments to specify which files or folders to act on. When typing them into Lingon, you must enter each of these items (normally separated by spaces) on a separate line (see screenshot).
The command you want to run is
rsync -aE /Users /Volumes/Backup/. This copies the entire contents of the Users folder to a volume named Backup—perhaps an external FireWire drive.
The rsync program is located in the /usr/bin directory, so after you click on the plus-sign button, double-click in the text field and type
/usr/bin/rsync. Next, click on the plus-sign button again and enter the flags
afor archive mode and
Efor extended attributes, such as resource forks) on the second line.
/Users, which specifies which folder to copy, goes on its own line, as does
/Volumes/ Backup/, which tells rsync where to copy the files. (On your Mac, fill in the name of an external hard drive, or type the path to another location.)
Note that for a launchd job that launches a regular application instead of a Unix command, you need the path not just to the application, but to the file that contains the executable code inside its package. For example, the path for iTunes would be
Make It Run You’ve indicated what will launch; the next (and trickiest) step is to define when it will launch. Lingon offers many options (see Launch Time for details). For this example, select just two.
In the Basic pane, select the OnDemand option. Leave the other options here deselected. (If you selected the RunAtLoad option, your job would run immediately; in this case, you want to specify a time.)
Click on the Miscellaneous tab. In the StartCalendarInterval text fields, type
1in the Hour field (and leave the other fields blank) to run this job every day at 1 a.m. Enter a different time—using a 24-hour clock, in which hour 0 (zero) is midnight—if your Mac is normally turned off or asleep at that time.
Load It Up Click on the Save & Load button to save your launchd job and load it into memory. (If you click on the Just Save button, your job will load automatically on your next restart or login.)
To temporarily disable a loaded job, click on the correct folder tab (for example, My Agents), find the job, and click on the Unload button. To load it again, click on Load. To disable a job permanently without deleting it, click on Edit, click on the Basic tab, and then choose the Disabled option.
Spring-load your drop box
Now that you have a feel for how to create launchd jobs, let’s try something different: a job that instantly moves anything placed in your Drop Box folder (/ your user folder /Public/Drop Box) to your desktop. That way, when another user on your network sends you a file, you won’t have to dig for it.
First, use your favorite text editor—for example, Bare Bones Software’s free TextWrangler —to create a simple script:
#!/bin/bash mv ~/Public/Drop\\ Box/* ~/Desktop/
Name the script DropBox and save it (or download it ). Open Terminal (/Applications/Utilities), type the command
chmod u+xfollowed by a space, and drag the file to the prompt to enter its path and name. Press return.
Open Lingon. Follow the same procedure as for the backup job, with a few modifications. Instead of selecting Users Daemons when you create the job, select My Agents so it will run only when you’re logged in. Click on the Basic tab and type a name—for example,
com.macworld.DropBox—in the Label text field.
Still in the Basic tab, click on the plus-sign button next to ProgramArguments. Double-click on the first line of the text field; then drag your DropBox script file from the Finder onto the first line of the ProgramArguments field to enter its name and path. Select the OnDemand option.
Click on the Paths tab. Click on the plus-sign button next to WatchPaths, double-click in the field, and enter
/Users/ your user folder /Public/Drop Box.
Click on Save & Load. To test the job, move any file into your Drop Box folder. The file should immediately disappear—and reappear on your desktop.
Troubleshoot your job
Code is picky, picky, picky! A stray space, incorrect capitalization, or a typo can sink your job. If a launchd job doesn’t work correctly, click on Unload to turn it off. Double-check your script (if there is one) by running it manually in Terminal. Then compare your job’s .plist contents, in Lingon’s Expert pane, with these screenshots. If everything matches, go to the Basic pane, ensure that the Disabled option is not selected, and click on Just Save. Click on Reload to reload the job.
[ Joe Kissell has written numerous e-books about Mac OS X software. ]