There’s an old saying “Linux will give you enough rope to shoot yourself in the foot!” and what that means is you’ve got power but you need to know how to use it. I’ve been using macOS (pka “Mac OS X”) for almost as long as I’ve been using Linux and I use the command line constantly in macOS and try to maintain a consistent experience between macOS and Linux when I can. I also tend to be late to install the most recent version of macOS.
So last year I wanted to set up a cron job to run a shell script to run rsync. On macOS. I tested things, added the cron job and it didn’t seem to work. I debugged, I tested, I searched… It seems macOS could not run an rsync job via cron. I tried to add cron, rsync, zsh, and iTerm, Terminal.app, and WezTerm to the “Full Disk Permissions” thing in the System Preferences. Eventually I gave up.
Well, eventually I created a workaround using Keyboard Maestro which has its own cron, and Platypus which wraps shell scripts in an Application, and that worked, but it’s overly complicated, so I’ll show you the way I do it now.
Launch Automator and create an Application…
Search for “shell” and you’ll see “Run Shell Script”. Drag it to the right side of the windows…
Type the path to your script.
/Users/pete/scripts/buRsync.sh 1>/Users/pete/scripts/buRsync.log 2>/Users/pete/scripts/buRsync.err
I’ve chosen to pipe the output and errors to files but you can skip that if you want. I also chose to use full paths.
Export the Application…
Give it a name and save it. You can put it right in the /Applications folder since it’s an actual macOS application.
Now you can add a cron job and use the macOS open command to open the application instead of trying to run a shell script directly.
0 6,18 * * * /usr/bin/open /Applications/RsyncApp.app
This seems to work fine for me in macOS Sonoma 14.6.1 but if it breaks in the future I’ll update this… if I don’t, just let me know!
Bonus: You can use the macOS Launcher to quickly and easily run shell scripts this way!
Yes, of course there is launchd but I think it’s overkill and a bit complicated for those who already know cron.