Mac launchd and launchctl — the OSX alternative to cron

I was revisiting my metrics project, having used the first one as the prototype to refine requirements (nothing works better at getting real requirements out of people than showing them something that doesn’t quite do what they want).

When it came time to test a monitor, I tried to get one running under cron and it didnt actually work for me. I can’t remember if cron has ever worked for me on a mac, but didn’t have the time to figure out why and how. It was time to make the jump to launchd.

Launchd is billed as an  init.d, /etc/rc, xinetd, .profiile, and crontab replacement, i.e. it can launch scripts at system startup, user login, or on a specified interval.

My use case was to do something cron like. This was not entirely straightforward, there is a difference between using StartCalendarInterval (to run things on a specified date, or every minute if no value is specified) and StartInterval (to run things at a specified interval, similar to specifying */5 for every 5 minutesin cron).

programs are loaded into launchd with launchctl, they are specified as plist files with a pretty simple key/value and/or key/dictionary of values XML format. Here is my .plist file for running something every 5 minutes:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
     <dict>
       <key>Label</key>
       <string>com.evri.metrics.deployment.cron</string>
       <key>ProgramArguments</key>
       <array>
          <string>/opt/local/bin/ruby</string>
          <string>/Users/arunjacob/hypertext/metrics_monitor/lib/tasks/deployment_monitoring/deployment_monitor_driver.rb</string>
          <string>deployment_aggregator</string>
       </array>
       <key>StandardErrorPath</key>
       <string>/dev/null</string>
       <key>StandardOutPath</key>
       <string>/dev/null</string>
       <key>StartInterval</key>
       <integer>300</integer>
       <key>RunAtLoad</key>
       <true/>
     </dict>
</plist>

Note that in key value parlance, StartInterval takes an integer which specifies the # of seconds. If I wanted to run something every day at a specified time, I would use StartCalendarInterval, which takes a dictionary element that contains time intervals.

<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
	"http://www.apple.
	com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
	<dict>
		<key>Label</key>
		<string>com.apple.periodic-daily</string>
		<key>ProgramArguments</key>
		<array>
			<string>/usr/sbin/periodic</string>
			<string>daily</string>
		</array>
		<key>LowPriorityIO</key>
		<true/>
		<key>Nice</key>
		<integer>1</integer>
		<key>StartCalendarInterval</key>
		<dict>
			<key>Hour</key>
			<integer>3</integer>
			<key>Minute</key>
			<integer>15</integer>
		</dict>
	</dict>
	</plist>

Note the difference between StartCalendarInterval syntax and StartInterval syntax — StartCalendarInterval takes a dict structure that contains key/value pairs. In other words it takes a hash. You can also use Arrays, as specified in the value for the ProgramArguments key. Just make sure your keys have the correct kind of values. as specified here.

Advertisements

2 Responses to Mac launchd and launchctl — the OSX alternative to cron

  1. arunxjacob says:

    one thing I forgot to mention is the launchctl command line —

    launchctl load {plist file} to load the job,
    launchctl unload {plist file} to unload it,
    launchctl list to list all plist jobs running.
    launchctl help to get more information.

  2. HD USB tuner says:

    HD USB tuner…

    […]Mac launchd and launchctl — the OSX alternative to cron « Wherever I go, there I am[…]…

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: