So you have a task that you want to run regularly on Linux/Unix. It could be a single commend, or a script that you prepared in advance that contains all the command you need run. What you need to do is to set up a “Cron job”. Cron is a system that, when the
cron program is running, reads a “tab” file for the instructions it needs, so that it can know *when* to execute *what*.
How cron works – Old School
The standard “Old School” design has
cron reading a tab file that is named after any given valid user (we’ll just focus on root for now), in a directory like:
…depending on your distro/version. The tab file contains single-line instructions in the form of:
minute hour day-of-month month day-of-week command
…whereas the smallest increment of time
cron can utilize is one minute, and “command” is either your single command or a script, preferably with the full path. Asterisks can be used in place of any given date/time stamp. For much more detail on the
crontab layout, see “
man 5 crontab“… and don’t forget the
Here is an example. Say you had written a script that you wanted to run every morning at 6:10am. You would have the following in your
10 6 * * * /home/jpavlov/bin/myScript.bash
How cron works – Modern
Most of this post will focus on the “Old School”
cron method, except for this section. The modern method of
cron is very similar, and in fact on many distros, you have both methods available to you. In this version though, the
cron tab file is located at has a slightly place (
/etc/crontab) that does not directly matter to you, because you do not enter items in this tab to get them executed. Because this tab is nothing but a “caller” to other scripts that execute items in a series of other directories, all under
cron.monthly. Any executable files in these directories will be executed at the interval after which they are named.
So, for instance, if you wanted a script to run daily, you can just copy the script into the
/etc/cron.daily directory (or create a link to it from there with
ln -s) and it will be run as
root at the next daily interval. If you only want a command executed, you can either add it to
/etc/crontab (not recommended, and it has a slightly different syntax, which I’m not going into), or just create a two-line script and do what I already described.
Ah, but “what *time* to they start”, you ask? This is dictated (or not) by entries in the
/etc/sysconfig/cron file, and I’ll allow you to read that and spare you more detail here. Just know that if you haven’t modified that file, the jobs run shortly after you boot, and the
cron clock is maintained off that time forward.
How to view or edit the
To view (list) the “Old School”
crontab, just do this:
crontab -l -u user
…and you can leave off the “
-u user” if you want to view your own crontab.
DO NOT edit the
crontab files directly (unless you *really* know what you’re doing). To edit the
crontab file, do this:
crontab -e -u user
This will launch an editor for you to use to modify the
crontab file. By design,
crontab on Linux/Unix machines will use the editor specified by the system variable “
EDITOR” to open the file. You can find out which one you have set (likely
vim) by typing
echo $EDITOR. If none is specified, it is
If you don’t like
vi, and prefer
gedit or something like it, you can modify that variable like this:
…which can be made system-wide permanent by adding it to
/etc/profile or similar.
I just want to mention how
cron integrates email notifications… When a job in the
crontab is executed, if there is any output, by default it is sent to
root (as dictated by your system, and any aliases, bla bla bla). A couple important points about that:
- The email destination may be changed *per
crontab*, not per job. Just change (or add) a line like this to the top of the tab:
- Also, your command or script might dump a lot of output (like debugging) that you may not want sent in a result email. So, the output of a job can be suppressed by adding a redirector at the end of the job line. I’ll demonstrate by updating the
crontabline from above with the redirector (all on one line):
10 6 * * * /home/jpavlov/bin/myScript.bash > /dev/null 2>&1
And that’s our lesson for today folks. Phew, that was a lot, but it really isn’t that complicated once you’re used to it… like anything else, I suppose.
If I missed anything, make sure and let me know!