What appears below are my personal notes I wish were part of my long-term memory but don't always seem to fit. I strive for accuracy and clarity and appreciate feedback. If applying any of this information anywhere, confirm for youself the correctness of your work as what you see below might very well be, albeit unintentionally, incorrect or misleading. These notes are here as an easy reference for myself.
Information worthy of a more formal presentation will appear elsewhere than this "Scratch" area. - ksb
I'm not sure I have ever written, even the simplest crontab entry, which worked as desired the first time. Herein are some hard-won lessons on how to write crontab entries.
|Table of Contents||References|
man 5 crontab
min hour day-of-month month day-of-week command 0 3 * * * $HOME/bin/nightliesThis, for example, will run the nightlies script at 3am each morning.
min hour day-of-month month day-of-week command MAILTOfirstname.lastname@example.org PATH=/usr/local/bin:/usr/bin:/bin 0 3 * * * $HOME/bin/nightlies
# min hour day-of-month month day-of-week command MAILTOemail@example.com */2 * * * * env | egrep ^PATH > $HOME/cron.out 2>&1This should print the contents of the $PATH env var used by cron to a file under your home dir and shows how to specify an every-other-minute cron job).
For example, changing the above example to:
# min hour day-of-month month day-of-week command MAILTOfirstname.lastname@example.org PATH=$PATH:$HOME/bin */2 * * * * env | egrep ^PATH > $HOME/cron.out 2>&1You might think would add ~/bin to your $PATH. Nope, you loose. In fact it effectively unsets the $PATH used so that now the env and egrep executables can't be found and nothing gets written to ~/cron.out. And you get an email like the following:
env: not found egrep: not found
What happens is the $PATH is not expanded into the value of the PATH env var. That newly added line will set your PATH to the literal (and meaningless) value '$PATH:$HOME/bin' not expanding the $HOME var either. Try this, instead:
# min hour day-of-month month day-of-week command MAILTOemail@example.com */2 * * * * PATH=$PATH:$HOME/bin env | egrep ^PATH > $HOME/cron.out 2>&1
A somewhat helpful trick is to try running your cron command directly via the shell, which gets you a bit closer to the way it will be run by cron:
/bin/sh -c "PATH=$PATH:$HOME/bin env | egrep ^PATH > $HOME/cron.out 2>&1"This isn't fool-proof but if it doesn't work this way, it certainly won't work via cron.
Most machines these days do not accept mail, for lots of good reasons. So if for some reason someone, or something generates a reply to that email, it would be nice to have that go someplace that won't bounce or clog up a mailq somewhere.
By default cron will set the From: field to be user@host, to change this you'll need to basically mail the results of your job manually, setting whatever mail headers you want. Here's a couple of ways to set the From: field of the emails you send.
# min hour day-of-month month day-of-week command MAILTOfirstname.lastname@example.org 0 1 * * * (printf "From: Nightly work <email@example.com>\nTo: firstname.lastname@example.org\nSubject: Nighly work\n\n" && $HOME/bin/nightlies) 2>&1 | /usr/sbin/sendmail email@example.com
# min hour day-of-month month day-of-week command MAILTOfirstname.lastname@example.org 0 1 * * * $HOME/bin/nightlies 2>&1 | /usr/bin/mail -a "From: Nightly work <email@example.com>" -s "Nightly work" firstname.lastname@example.orgThese both allow has the nice side-effect of being able to set the subject of the email to something better than the ugly default cron uses.
Yes, you will do best to include both the To: header and the destination for sendmail, since some mail list will complain about "implicit sender".
Also, if you're going to this much work, you might as well move the job into it's own script.
The '%' char in crontab files has a special meaning. Read the man page if you really want to know but this clobbered me when using the date command with a format string in it. You need to quote the % char in the normal way to avoid that special meaning:
# min hour day-of-month month day-of-week command MAILTOemail@example.com 0 1 * * * cvs -Q -d /path/to/cvs/repo up -D `date +\%Y-\%m-\%d` /path/to/cvs/workspace