3

Is there "a right" way to run shell scripts on a schedule in modern versions of MacOS? My usual go to for this has been using the cron command -- but recent changes make seem like this isn't in the front of Apple's mind these days.

Is there a better option than cron for running programs on a schedule in modern (Big Sur era) MacOS? Is my only option biting the bullet and learning how launchd works or is there something simpler/easier that I can use?

3
  • 1
    Apple recommends using launchd and while it's a bit of a handful learning it from the various manual pages around it, launchctl, launchd.plist and launchd, there are third-party applications that present a GUI interface to it. One of which that I've used in the past is Lingon, however there are a few more of them out there. Commented Aug 21, 2021 at 20:10
  • 1
    launchd jobs are subject to the same permissions restrictions as cron jobs (see "How to run a LaunchAgent that runs a script which causes failures because of System Integrity Protection", for example). Personally, I don't see any great need to switch from cron, if that's what you're more comfortable with (at least at this point). But if you do need to switch, launchd is definitely the system to switch to. Commented Aug 21, 2021 at 20:47
  • That's good to know @GordonDavisson -- this particular question was prompted by an issue with setting up a new cron job that was silently failing, leaving me guessing as to what was causing the failure and being unable to rule out System Integrity Protection (even though a second cron job is running fine). If launchd suffers the same sorts of issues that's good to know. A bummer, but still good to know. Commented Aug 21, 2021 at 21:25

2 Answers 2

3

If there is a “right” way from Apple’s point of view, then it’s launchd. Not that cron is “wrong” per se but it is not the “preferred” way.

However, as you indicated, launchd can be a pain to work with.

There are two good apps to try:

  1. https://www.soma-zone.com/LaunchControl/ ¹

  2. https://www.peterborgapps.com/lingon/

Lingon has been around for a long time and is probably better known, but I switched to LaunchControl a few years ago and much prefer it.

The developer also maintains https://launchd.info which is a helpful tutorial website to understand how launchd works.

LaunchControl also has a built-in tool that can mitigate issues around Full Disk Access, making it easier to deal with macOS' restrictions.


There is another, simpler option: Keyboard Maestro. Not only does Keyboard Maestro have a feature to run scripts (or macros, etc) at a specific time or recurring every X minutes, but you can also use cron-style syntax if you want.

Given that Keyboard Maestro is the best automation tool for the Mac, and I'd probably sacrifice a finger rather than be forced to use a Mac without it, you can guess that I strongly recommend Keyboard Maestro. It has a free trial (for other 2 weeks or 30 days, I'm not sure, but it's definitely a long time) and is actively maintained.


¹ As of this writing, both the LaunchControl website and launchd.info site appear to be down, which I assume is just a temporary glitch. They were working as recently as last night. If it is still down when you read this, you can download a copy of the latest version (which also has a free trial) from my website here:

https://iusethis.luo.ma/launchcontrol/LaunchControl-1.52.3.tbz2

2

You can still use crontab in the same way as you do it on a linux box — MacOS does not run a real cron service and crontab is just a wrapper that delegates to launchd saving you the need to bother with the launchd XML syntax (see under Running a Job Periodically).

Go ahead and create your cron entries using the familiar syntax by running as your regular user:

crontab -e

NOTE: You can also use sudo crontab -e if your task needs to be run as root. You need to make sure that the root user has access to your script though.

Example entry:

0 8 * * * /usr/local/bin/myscript.sh >> /tmp/myscript_errors.log 2>&1

List existing crontab entries:

crontab -l

When cron jobs generate output MacOS creates local mail entries which could show up as You have new mail notifications when you open a new terminal shell. To disable local mail messages add to the top of your crontab the following line:

MAILTO=""

PS: Depending on the version of your MacOS you might need to allow full disc access to /usr/bin/crontab as described in this answer.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .