Mac is user friendly, right? Well yes, until it isn’t.
These days, many people develop software using VMs or Dockers or Docker-isch container systems. In such cases, you never really need to care about how to setup stuff like cronjobs and such on your local machine since the VM is probably running a *nix flavor of your choice and you are quite familiar with those.
Enter 2018. VMs on macOS are not resource friendly anymore, so many of you (me included) have skipped the VM step in order to have MySql, Redis, PHP, Nginx etc running locally. It saves RAM and runs faster by a magnitude.
So, here we are then, needing to setup a cronjob on macOS. It’s not very different from Linux since macOS was once a *nix OS itself, but there are some changes.
Please note! If you are dead set on going the mac way, you should not use cronjobs at all, but rather use launchctl, but for the purpose of this tutorial, we stick with what we know and what works for us.
For the sake of simplicity, say we want to run a PHP script every hour. Start by typing the following in a terminal window:
Make a note of the path that you get as an answer from that command since cronjobs run without knowing anything about your path. You can of course set the path in the crontab but that’s just cluttering things up and makes your solution less portable. Stick with full paths.
In fact, let’s prepare the cron command you want to run so you can just copy and paste it into the crontab since we’ll run that in VI-mode and that can be pretty tedious if you are not used to it. So, in my case the cronjob I want to run looks lik so:
# m h dom mon dow command #hourly statistics calculations 1 * * * * /usr/local/bin/php /Users/martin/crons/hourlystats.php
That’s what my crontab will look like. I’ve put in two commented rows. The number sign (#) means the row will be ignored so you can write helpful or at least somewhat meaningful stuff on such row.
The top row just reminds me what a cronjob should look like i.e. the minute, hour, day of month, month, day of week. With this notation, you can run a cronjob at any sequence spanning from each minute to once a year. As you can see, this cronjob will run on minute 1 of each hour, each day, each month, each year. Another way to say the same thing: once an hour or just hourly.
Now, copy the text you want to paste, somewhat resembling what I have in my cronjob above. Be sure to change the user name to your name and have it point to your file etc.
Fire up iterm2 (or your favorite terminal software on your mac) and type the following. Warning, VI/Vim notation awaits.
Now you are looking at an empty file in VI-mode. This may seem scary but it’s a piece of cake.
Press letter i.
Paste the text with CMD + V.
Now press ESC.
Now type :wq followed by Enter.
Done. You have now successfully created a cronjob in macOS.
If you want to see where the actual file is stored, just to make sure it actually got installed, type the following in your terminal window:
Again, substituting martin for your username (the foldername of your home folder in your macOS).
You should now see your cronjob in that file, ready to be executed next hour:01, so to speak.
To get out of the file, just type :q!
How do I know if the cronjob executed?
For the first couple of times, it’s really good to know if the cronjob executed ok or not. A nifty feature to easily view the outcome of your cron is to fire up your terminal and type
This will let you see all the cronjob executions in numbered rows.
Simply type the number of the cron execution you want to see the result from.
After a while, if you are tired of filling up the local mailbox (this is not your e-mail box), you can fire up your terminal once again and type
And in the crontab, you press i for insert mode and paste the following at the top:
Type :wq followed by Enter.
Done. No more mails when cronjobs execute.