Apple/Mac launchd
FAQ: Can you share some MacOS launchd examples (also written as launchd plist examples, or launchctl examples)?
In an earlier tutorial (MacOS startup jobs with crontab, launchctl, and launchd) I demonstrated how to use the macOS launchd
facility instead of the Unix cron
command to run what would normally be a cron/crontab job. As I started working with launchd
and launchctl
, I realized it would probably be helpful to see several different launchd
examples, specifically launchd
plist file examples, so I share those here.
A first Mac launchd/launchctl example (a launchd plist file)
As a first MacOS launchd example, here's the Mac plist file I showed in my other tutorial:
<?xml version="1.0" encoding="UTF-8"?> http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>label</key> <string>com.devdaily.pingwebsites</string> <key>ProgramArguments</key> <array> <string>/Users/al/bin/crontab-test.sh</string> </array> <key>OnDemand</key> <false/> <key>Nice</key> <integer>1</integer> <key>StartInterval</key> <integer>60</integer> <key>StandardErrorPath</key> <string>/tmp/AlTest1.err</string> <key>StandardOutPath</key> <string>/tmp/AlTest1.out</string> </dict> </plist>
As mentioned in that Mac launchd tutorial tutorial, this launch plist script does the following things:
- Runs a Unix shell script named
/Users/al/bin/crontab-test.sh
. - Runs that script every minute, as given by the
StartInterval
tag. - Assigns the label "com.devdaily.pingwebsites" to this script. This is helpful when you use the
launchctl
command, as discussed in the earlier tutorial.
A second MacOS launchd example
I found this second Mac launchd plist file example on both of my MacOS systems:
<?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>Label</key> <string>com.google.keystone.user.agent</string> <key>LimitLoadToSessionType</key> <string>Aqua</string> <key>ProgramArguments</key> <array> <string>/Users/al//Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/Resources/GoogleSoftwareUpdateAgent.app/Contents/MacOS/GoogleSoftwareUpdateAgent</string> <string>-runMode</string> <string>ifneeded</string> </array> <key>RunAtLoad</key> <true/> <key>StartInterval</key> <integer>3523</integer> <key>StandardErrorPath</key> <string>/dev/null</string> <key>StandardOutPath</key> <string>/dev/null</string> </dict> </plist>
I assume this Mac launchd
plist file is on both systems because I use the Chrome browser, but I don't know that for a fact.
As you can see from this Mac launchd
example:
- The Mac
launchd
plist "label" for this plist file is "com.google.keystone.user.agent". - This script runs every 3,523 seconds. Sorry, I don't know why they use that specific value. (3,600 seconds would be one hour.)
- I don't know what their
ProgramArguments
are. Those will be specific to the program being run.
MacOS system launchd plist example files
A great source for Mac launchd
examples are these two directories on your MacOS system:
/System/Library/LaunchAgents
and
/System/Library/LaunchDaemons
These Mac folders have dozens of launchd
plist example files. Be careful not to edit these files in place, as they are important to how your MacOS system runs. Just browse them in place, or copy them to another location if you want to really dig into them.
Just looking at a few Mac launchd
examples here, the MacOS launchd
plist file for Spotlight is surprisingly simple:
<?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.Spotlight</string> <key>ProgramArguments</key> <array> <string>/System/Library/CoreServices/Spotlight.app/Contents/MacOS/Spotlight</string> </array> <key>KeepAlive</key> <true/> </dict> </plist>
The only thing they're really doing there is using the KeepAlive
tag.
On the other hand, their ssh.plist
file is much longer, and demonstrates several other pieces of the Mac plist vocabulary:
<?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>Disabled</key> <true/> <key>Label</key> <string>com.openssh.sshd</string> <key>Program</key> <string>/usr/libexec/sshd-keygen-wrapper</string> <key>ProgramArguments</key> <array> <string>/usr/sbin/sshd</string> <string>-i</string> </array> <key>Sockets</key> <dict> <key>Listeners</key> <dict> <key>SockServiceName</key> <string>ssh</string> <key>Bonjour</key> <array> <string>ssh</string> <string>sftp-ssh</string> </array> </dict> </dict> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict> <key>SessionCreate</key> <true/> <key>StandardErrorPath</key> <string>/dev/null</string> <key>SHAuthorizationRight</key> <string>system.preferences</string> </dict> </plist>
I believe this script is used as a replacement for a more "normal" inetd or xinetd entry, as indicated by the "inetdCompatibility" tag. While I'm pretty certain this is true, I haven't created an inetd daemon using launchd yet.
A Google plist example
Here’s a nice example that Google has on my computer:
<?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>AbandonProcessGroup</key> <true/> <key>Label</key> <string>com.google.GoogleUpdater.wake</string> <key>LimitLoadToSessionType</key> <string>Aqua</string> <key>ProgramArguments</key> <array> <string>/Users/al/Library/Application Support/Google/GoogleUpdater/Current/GoogleUpdater.app/Contents/MacOS/GoogleUpdater</string> <string>--wake-all</string> <string>--enable-logging</string> <string>--vmodule=*/components/update_client/*=2,*/chrome/updater/*=2</string> </array> <key>StartInterval</key> <integer>3600</integer> </dict> </plist>
The ProgramArguments
setting in this example is particularly helpful.
KeepAlive
Here’s a KeepAlive example from a Samsung plist file on my computer:
<?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>KeepAlive</key> <dict> <key>SuccessfulExit</key> <false/> </dict> <key>Label</key> <string>com.samsung.portablessd.mon</string> <key>ProgramArguments</key> <array> <string>/Users/al/Library/Application Support/PortableSSD/SamsungPortableSSD.app/Contents/Resources/SamsungPortableSSDMon</string> </array> </dict> </plist>
StartCalendarInterval and running every day of the week
In a related note, this is the approach that seems to be required to run a script or command every day of the work week, Monday through Friday:
<key>StartCalendarInterval</key> <array> <!-- SUNDAY (testing) --> <dict> <key>Weekday</key> <integer>0</integer> <key>Hour</key> <integer>16</integer> <key>Minute</key> <integer>00</integer> </dict> <dict> <key>Weekday</key> <integer>1</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>2</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>3</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>4</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>5</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> </array>
While the approach is verbose, I can verify that it works. The first “Sunday” entry is for tests that I ran when I was creating my plist file, and the other entries are for Monday through Friday. Note that the integer value for Sunday is both 0 and 7, so you can use either of those for its Weekday
entry.
FWIW, this is my complete /Users/al/Library/LaunchAgents/com.alvin.stocksapp.plist file for a “stock market quotes” app that I recently created:
<?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>Label</key> <string>com.alvin.stocksapp</string> <key>ProgramArguments</key> <array> <string>/Users/al/AlsStocksProject/Version04/GetStocks.sh</string> </array> <key>Nice</key> <integer>1</integer> <!-- <key>StartInterval</key> <integer>60</integer> <key>ThrottleInterval</key> <integer>120</integer> --> <!-- 0 and 7 == Sunday --> <key>StartCalendarInterval</key> <array> <dict> <key>Weekday</key> <integer>1</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>2</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>3</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>4</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Weekday</key> <integer>5</integer> <key>Hour</key> <integer>11</integer> <key>Minute</key> <integer>0</integer> </dict> </array> <key>RunAtLoad</key> <true/> <key>StandardErrorPath</key> <string>/Users/al/StocksApp.err</string> <key>StandardOutPath</key> <string>/Users/al/StocksApp.out</string> </dict> </plist>
More Mac launchd example files (plist files)
I could share many more Mac launchd
examples here, but since you can find dozens of examples on your own MacOS system in the two directories shown above, I'll skip that. I think the important thing here is that you can use vi or grep to browse these example plist files for what you're looking for, and once you find what you're looking for, just include the necessary pieces in your own launchd
plist file.
Again, for more information on the MacOS launchd
facility, see my (MacOS startup jobs with crontab, er, launchd tutorial). That Mac launchd
tutorial includes a more detailed description of launchd
and plist files, with several links to the Apple launchd
documentation.