MacOS ‘launchd’ examples (launchd plist example files)

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.