Skip to content

Instantly share code, notes, and snippets.

@todgru
Last active April 20, 2023 17:54
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save todgru/4503682 to your computer and use it in GitHub Desktop.
Save todgru/4503682 to your computer and use it in GitHub Desktop.
Launchd and plist, replace cron in Mac OS X

#launchd Usage

I have a bash script called foo.sh that takes one command line argument, bar. I want it to run every 60 seconds and load at startup.

  • an XML plist is Apple Property List
  • com.mydomain.foo.plist Name of launchd plist file should be a reverse fqdn, like (this may not be required, but convention)
  • com.mydomain.foo.plist lives in $HOME/Library/LaunchAgents and is ran as that user.
  • com.mydomain.foo.plist can also live /Library/LaunchDaemons or /Library/LaunchAgents, have requirements, ran as root
  • Load plist with launchctl load com.mydomain.foo.plist
  • Unload plist with lauchctl unload com.mydomain.foo.plist
  • Check /var/log/system.log if you are having issues with plist

from http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/ScheduledJobs.html

"If the system is turned off or asleep, cron jobs do not execute; they will not run until the next designated time occurs. If you schedule a launchd job by setting the StartCalendarInterval key and the computer is asleep when the job should have run, your job will run when the computer wakes up. However, if the machine is off when the job should have run, the job does not execute until the next designated time occurs."

Example plist for foo.sh

<?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.mydomain.foo</string>

    <key>ProgramArguments</key>
    <array>
      <string>/path/to/foo.sh</string>
      <string>bar</string>
    </array>

    <key>Nice</key>
    <integer>1</integer>

    <key>StartInterval</key>
    <integer>60</integer>

    <key>RunAtLoad</key>
    <true/>

    <key>StandardErrorPath</key>
    <string>/path/to/foo.err</string>

    <key>StandardOutPath</key>
    <string>/path/to/foo.out</string>
  </dict>
</plist>

for reference:

@dhinostroza
Copy link

dhinostroza commented Oct 25, 2019

Hi,
Following your example, I have the following lines inside my foo.sh:

REDCap Cron Job (runs every minute)

          • /usr/bin/php /Applications/MAMP/htdocs/redcap/cron.php > /dev/null
            (5 asterisks)

But I'm getting the following error message in foo.err:
/Users/ssd/bin/crontab-test.sh: line 2: Applications: command not found

I guess the old crontab format needs to be reformatted for launchd to understand it.
Can you give me some insight on this?
Best,
Daniel
dhinostroza AT gmail.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment