How do you configure a launchd plist to execute every 5 minutes ON the 5 minute multiple?

Simce SIP has now locked us out of being able to enable and configure crontab entries, I'm trying to create a plist that will execute my task every 5 minutes on the 5 minute multiple (0, 5, 10, 15, etc.). I know that I can set the StartInterval at 300 to get 5 minute separation, but there's no way to guarantee that this will fall on the 5 minute multiples.


Reading about StartCalendarInterval implies that I should be able to do the same thing that I do with CRON:


<key>StartCalendarInterval</key>
<dict>
  <key>Minute</key>
  <integer>*/5</integer>
</dict>


However, that runs continously every 6 to 10 seconds.


I then tried creating an array of separate minute entries:


  <key>StartCalendarInterval</key>
  <array>
    <dict>
      <key>Minute</key>
      <integer>0</integer>
    </dict>
    <dict>
      <key>Minute</key>
      <integer>5</integer>
    </dict>
    <dict>
      <key>Minute</key>
      <integer>10</integer>
    </dict>
    <dict>
      <key>Minute</key>
      <integer>15</integer>
    </dict>
   ...
 </array>


And that had the same result of running continuously every few seconds instead of once every 5 minutes. How should I create a plist that will achieve the 5 minute repeat on the 5 minute multiple in a launchd plist?

Reading about StartCalendarInterval implies that I should be able to do the same thing that I do with CRON:

<key>StartCalendarInterval</key> 
<dict> 
<key>Minute</key> 
<integer>*/5</integer> 
</dict>

The man page says that the “semantics are similar” to CRON. However, the syntax is not. This approach is not going to work because

*/5
is not a valid integer in the property list spec.

You can double check that your property list is at least syntactically correct using

plutil -lint
. For example, if I put the above into a launchd property list file I see this:
$ plutil -lint Library/LaunchAgents/com.example.apple-samplecode.FiveMinuteTest.plist
Library/LaunchAgents/com.example.apple-samplecode.FiveMinuteTest.plist: Unknown character '*' (0x2a) in <integer> on line 14

I then tried creating an array of separate minute entries:

This approach seems more feasible. I tried this out here in my office and it worked for me. Specifically, I created a launchd property list that looked like this:

$ cat Library/LaunchAgents/com.example.apple-samplecode.FiveMinuteTest.plist
<?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.example.apple-samplecode.FiveMinuteTest</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/quinn/FiveMinuteTest.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Minute</key>
            <integer>0</integer>
        </dict>
        <dict>
            <key>Minute</key>
            <integer>5</integer>
        </dict>
        <dict>
            <key>Minute</key>
            <integer>10</integer>
        </dict>
        <dict>
            <key>Minute</key>
            <integer>15</integer>
        </dict>
        …
    </array>
</dict>
</plist>

It references a shell script that looks like this:

$ cat FiveMinuteTest.sh
#! /bin/sh

date >> /Users/Quinn/FiveMinuteTest.txt

I loaded it like this:

$ launchctl unload Library/LaunchAgents/com.example.apple-samplecode.FiveMinuteTest.plist

And I monitored the output like this:

$ tail -f FiveMinuteTest.txt
Mon Oct 19 10:00:05 BST 2015
Mon Oct 19 10:05:05 BST 2015
Mon Oct 19 10:10:05 BST 2015
…

I was testing on 10.10.5 but I’ve no reason to suspect that this was broken by 10.11.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

My test plist is just like yours except for the script that is executed. I changed my script and I get 11 entries every 5 minutes. Something's definitely odd.

I changed my script and I get 11 entries every 5 minutes.

Just to clarify, I interpreted that to mean that:

  1. you replicated my setup and it works as I described

  2. you then tweaked it to run your script rather than my script and it started failing

Is that correct?

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I back up critical files on my wife's Mac every morning at 2am. I have a cron job that

starts at 2am and I have the system wake up at 1:55 to be ready for it. I updated her

system to 10.11 two weeks ago and the backups stopped working. I noticed that cron

is "deprecated", and I presume that the update effectively stopped it from working.

(Happy to know otherwise if I'm wrong ... but certainly something happened to cron.)


I'm unable to get the launchctl approach to work. Details below. Desperate for

help to get the .plist file to start up.


So I started to prototype how to do the same thing as cron with launchctl by scheduling a

small task on my own Mac. The task is to start a shell script "mailjob" to send

me an email message every minute. The script works fine when invoked with

"bin/mailjob".


I want her backup to run under her uid. So in my prototyping, I want the .plist

file to be in ~/Library/LaunchAgents/ . File listed below. I've checked it

for syntactical correctness, and I modeled it after a working com.adobe .plist file,

so I think it's correct.


The problem is that I can't get the task to load and/or start with launchctl. The

added commands and nomenclature associated with the 10.11 update didn't help ...

they're very unclear, and there aren't any tutorials. So I've tried both the

newer "bootstrap" command approach and the older "load"/"start" command approach,

but I cant' get either one to work.


Could someone who knows something about this system please look this over and

tell me what I'm doing wrong? I'm sure it's a trivial misunderstanding of

the launchctl command syntax, but after hours of working on it, I haven't

figured it out.


So, given the "~/bin/mailjob" shell script I want to execute every minute,

and given the .plist file listed below,


1) Start with this (mailjob not listed):

HDT:~ hdtodd$ launchctl list | grep mail

- 0 com.apple.mdworker.mail

HDT:~ hdtodd$


2) Try "bootstrap" but it doesn't load anything:

HDT:~ hdtodd$ launchctl bootstrap user/502/com.examples.mailjob ~/Library/LaunchAgents/com.examples.mailjob.plist

HDT:~ hdtodd$ launchctl list | grep mail

- 0 com.apple.mdworker.mail

HDT:~ hdtodd$


3) Try "load" and "start"; it loads mailjob but nothing starts:

HDT:~ hdtodd$ launchctl load ~/Library/LaunchAgents/com.examples.mailjob.plist

HDT:~ hdtodd$ launchctl list | grep mail

- 0 com.examples.mailjob

- 0 com.apple.mdworker.mail

HDT:~ hdtodd$ launchctl start com.examples.mailjob

HDT:~ hdtodd$ launchctl list | grep mail

- 0 com.examples.mailjob

- 0 com.apple.mdworker.mail

HDT:~ hdtodd$ mail

No mail for hdtodd

HDT:~ hdtodd$


BUT ... I do get this message from "syslog -w":

Feb 19 12:22:18 HDT com.apple.xpc.launchd[1] (com.examples.mailjob) <Notice>: Service only ran for 6 seconds. Pushing\

respawn out by 4 seconds.


How do I get launchctl to actually schedule and start the task pointed to by the .plist file?

How do you configure a launchd plist to execute every 5 minutes ON the 5 minute multiple?
 
 
Q