Strangely, one of the earliest things I learned in unix computing was
crontab -e. In fact, it would not be an exaggeration to say, the reason I learned to
vim in the first place, was so I could fire off automated jobs in
while I slept (Don’t ask. Mine was a complex childhood. :-) ).
I’ve never been a fan of Apple’s
launchd replacement on the OSX operating
cron has its shortcoming to be sure, but it’s unix-y, simple, and let’s face
it… gets things done, plus, it works on millions of systems worldwide. While
I get that Apple wanted to replace the historical soup that was
other things), I’ve always felt
launchd was painful. Admittedly, this might
just be because I’ve always found
cron so unbelievably fit-for-purpose when
you actually know how to use it.
Apple seems to have gone out of its way to make
cron a bit tricky for you to
enable, but after some substantial googling and experimentation, I thought I’d
write it down so you don’t have to go through the same rigmarole.
What You Don’t Get
Before you enable your
crontab though, just a few caveats on what you do get
launchd, just in case you’d rather use one of the GUI apps to interface
with that and solve the same problem, instead of going this route.
The main thing, is that
launchd tasks will check upon upon waking from
sleep, whether a specific tasks was scheduled to run during sleepy time ran, and
then run it if it was supposed to (note: this does not apply if the system was
off or similarly during that time, afaik)
The other thing you can do is to use
launchctl to write background tasks
that run, so you could get around things this way as well:
launchctl submit -l task1 — $HOME/bin/task1.sh foo bar
But personally, I find the XML configuration of the plists painful and a step
down from the simplicity of a
Enable system cron
In a nice touch though, you can get
launchd to fire up the system (root)
cron, if you simply do this:
🚀 ~ sudo touch /etc/crontab
You probably will need to reboot in case
launchd doesn’t want to launch it,
but doing that means that
launchd will see cron and launch it on startup.
(nb: unless you really know what you’re doing do not mess with the
/etc/crontab file. Run all your cron jobs under your user account.)
Getting cron running for users under your crontab
The easiest way after you’ve got the above goingi, is to simply create a file
.crontab in your home directory. Cron will automatically pick this up
for you and start running it if it’s present on startup.
The canonical way to do this is the following command:
🚀 ~ crontab -e
which will dump you into the old-school-y (yet surprisingly resurgent) editor
vim. If you’ve never used it before, well… it may be a bit of a shock. I
certainly recommend investing the time to learn, but assuming you are in oh my
god, just tell me how to get this working! mode, type this in the command line
🚀 ~ export EDITOR=nano
(nb: if you’re stuck in vi at the moment, hit
:q! to exit and get back to
the command line and do the above.).
Once you’re in the vi editor, it’s really just simple text editing.
For example, here’s the line I put in to do routine, weekly back ups of my Gmail using Gmail Vault (I’d recommend having the logging going in case you need to debug things.):
15 13 * * 1 /usr/local/bin/gmvault sync -t quick -d /Users/me/mail_backup_dir me@.example.com > ~/mail_backup_dir/gmvault.log 2> ~/mail_backup_dir/gmvault-error.log
(nb: all the above should be on one line in your crontab, not split over 3)
Admittedly, you could make this shorter without the logging, but I like having that in there for checking and goof proofing. What this cron does is run the gmvault quick sync command to a specified backup directory every Monday at 1:15 pm.
Exit vim, remembering to save the file (
:wq), and then do a
crontab -l to
make sure it stuck. This should list the contents of the crontab file.
Normally, this should just work, but if it appears that cron still isn’t working
you can also give it a kick with
And believe it or not, you may still not be there.
Again, some little quirks with Apple’s (admittedly fabulous) OSX may be tripping you up.
If you are in vim (the default for editing on
crontab -e and do the funky
:wq to write and quit and you get,
crontab: "/usr/bin/vi" exited with status 1
you will annoyingly find your changes have not been saved. What gives, right?
Apparently, this has to do with the way crontab wants temporary files to work
and how it names them. Suffice it to say, there are a few ways around this. The
one I added to my
.vimrc since it seemed the least intrusive was:
crontab -e back up again after saving the above and any changes made to
the crontab should be saved.
An even better solution someone posted on the Vim Wikia is a lot more specific in case you don’t like the idea of the above solution.
au BufEnter /private/tmp/crontab.* setl backupcopy=yes
There are a few other ways you can accomplish the same thing, but the others involve editing in multiple places or in the bash profile and are not as clean as this one which is fairly vim specific.
And that, is how you get
cron enabled and running on OSX Yosemite.
cron tasks have been chugging away quite happily over the past few weeks
and I have to admit I’m a lot happier for my OSX working the way I want. While I
realize that a number of Linux distros have also attempted to replace the
initd startup with their solutions, Upstart being the one most recognizable,
I’m assuming cron is still the word in the Linux world. Glad to have it back on