Scheduling Cron Jobs with Crontab [The Complete Guide]

In this lesson we’re going to look at How you can use the cron daemon to schedule jobs to run in the future on a schedule that you specify.

Understanding crontab

Now as you know, the at daemon can also do the something, you can use it to schedule a job to run at a later time in the future.

However, be aware that the at daemon has one key drawback and that’s the fact that it can only schedule a job to run once in the future.

Now that’s not a problem if you only want the job to run once in the future.

However, there will be many times when you want a job to run in the future on a regular schedule, for example, you may want to run your backup every day at a particular time.

In this situation, the at daemon really doesn’t cut it because you’d have to define new at job every single day to run your backups and that’s really not all that useful.

Instead what we need is a tool that can handle a repetitious schedule and the cron daemon can do just that.

Unlike at cron can run commands on a schedule that you specify over and over and over.

So, in this lesson we’re going to talk about how cron works and then how you can use cron to schedule jobs in the future.

How the cron daemon Works

So, let’s begin by talking about how the cron daemon itself works.

The cron daemon runs when the system is booted up and it runs continuously in the background and it checks special files called crontabs files once every minute to see if there’s a job scheduled that it needs to run.

If there is it runs it, if not it waits and checks again in the next minute.

Types of Cron Jobs | Directory path | Crontab Syntax and Operators

Now understand that you can configure cron to run two different types of jobs.

You can run System jobs or you can run User jobs.

We’re going to look at both of those.

System Cron Jobs

We’re going to begin, however, by talking about running System jobs.

Now using cron to run System jobs on a schedule is an extremely useful tool for a Linux administrator.

Using cron you can schedule certain jobs to run on a regular schedule and that saves you a ton of time and effort.

Crontab Directory Path

So, to run system jobs the cron daemon uses this file right here /etc/crontab.

The /etc/crontab file specifies what system jobs the cron daemon should run, an example of a crontab file is shown right here.

# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# check scripts in cron.daily, cron.hourly, cron.monthly, and cron.weekly

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

* * * * * root test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1

The /etc/crontab file contains this one command righ there that tells the cron daemon to run scripts that are located in these four directories.

  • The first one in the /etc/cron.hourly/ which contains cron scripts that should be run every single hour of the day.
  • There’s also a directory in /etc/cron.daily/ which contains scripts that should be run once a day.
  • There’s also directory /etc/cron.weekly/ that contains scripts that cron needs to run once a week.
  • And then finally there is a directory called /etc/cron.monthly/  that contains scripts that cron needs to run once a month.

So, any script that’s found in any of these four directories is run automatically by chronological order to the specified schedule.

For example, in the /etc/cron.daily/ directory there are scripts that perform a wide variety of tasks.

For example, we have a script called logrotate, this script contains the commands necessary to rotate your system logs and because it’s in the daily directory it is run once a day.

This is designed to keep your log files from getting too big to keep them manageable and to back them up every so often.

# ls /etc/cron.daily/
logrotate  rhsmd

Suggested Read: How do I list files in Linux

So, if you have a system task that you need to be run according to one of these four different schedules Hourly, Daily, Weekly, or Monthly all you have to do is create a script file that has the commands that you need within it and then copy it into the appropriate directory in /etc.

What do you do however, if you have a system job that needs to be run on a schedule, but the schedule required doesn’t fit the four different categories represented by those four cron directories?

Basically, you need it to run on a custom schedule what do you do?

Well in addition to the four directories we just talked about there is a fifth directory in /etc directory called /etc/cron.d/.

If you have a system job and you need it to run on a custom schedule you create what’s called a crontab file in this directory.

This crontab file will be read by the cron daemon and the commands contained within it will be run for you according to the schedule that you specify.

Understanding Crontab Syntax and Operators

Now a sample crontab file is shown here.

# cat /etc/cron.d/crontab
0 5 * * 1 root test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1

The crontab file is just a text file and it has one cron job per line.

Now each line has 6 different fields and they’re separated by tabs, here’s field1, field2, field3, field 4, field 5 and then the rest is field6.

Cron job
Cron job

These different fields configure how the cron job will be scheduled.

For example, let’s suppose that I want to back up the /home directory and I want to do that using the tar command.

I want the backup to occur every day of the week except for Sundays because nobody’s at work on Sunday and I need it to run at 11:05 p.m. later at night when everybody should be gone and not working on the system.

I want to run the tar command, I want it to back up the /home directory and I want to save it to a file named home_bak.tar which will be saved on a removable USB hard disk that has been mounted in /media/usb/.

I can accomplish this using the crontab file shown here.

# cat /etc/cron.d/crontab
5 23 * * 1-6 /bin/tar -cvf /media/usb/home_bak.tar /home

Let’s take a look at what each of the fields in this crontab file do.

Before that, you look at this chart and some Important Operators, which will make it easier for you to understand.

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

Important Operators:

  1. * – The asterisk operator means any value or always.
  2. , – The comma operator allows you to specify a list of values for repetition.
  3. - – The hyphen operator allows you to specify a range of values.
  4. / – The slash operator allows you to specify values that will be repeated over a certain interval between them.

Now let’s take a look at what each of the fields in this crontab file:

  • 5 – The first field is the Minutes field, this specifies how many Minutes past the Hour that you want the command to be run.
  • 23 – The next field is the Hour field, this specifies the Hour of the Day when you want the command to be run.

    So basically, these two fields together specify the time of Day when the command should be run, In this case we’re going to run the command at 23:05.

    Now as you can see here cron prefers the 24-hour clock.

    So, if we subtract 12 from 23 we get 11 o’clock p.m. and because we put 5 in the minutes field this command is going to be run at 11:05.
  • * – The next field specifies the Day of the Month that you want the command to be run.

    Notice here that I used an asterisk (*) character that means every Day of the Month.

    If you had a command that you only wanted to run on a particular Day of the Month, you could put the number of that day of the Month here.

    For example, you may have a command that needs to be run on the 15th of every month and only on the 15th of every month well you’d put that number 15 in this field.
  • * – The next field is the Month field this specifies the Month of the year when the command should be run.

    In this case again I’ve used an asterisk (*), so that means I want the command to be run every single month of the year.

    If that weren’t the case, I would put the number of the month in this field instead.
  • 1-6 – And then finally we have the day of the week that we want the command to be run on.

    Now as far as cron is concerned Sunday is Day 0 and Saturday is Day 6, So you could specify one particular day of the week when you want the command to be run.

    For example, if I put 5 in this field the command would only be run on Fridays or I can put a range as I’ve done here 1-6.

    This indicates that the command should be run on Monday, Tuesday, Wednesday, Thursday, Friday, and Saturday but not on Sunday.
  • And then the Sixth field over here is the actual command that we want the cron daemon to run.

Now notice that we had to use the full path over here to the tar command and that’s different than what you’re used to when running a command at the shell prompt.

Just be aware that the cron daemon does not use the path environment variable to find the command to run.

So, you have to put the full path and if you don’t know what the full path is to the command that you want to run, use the which command at the shell prompt.

Type which followed by the name of the command and it’ll tell you where that command is located.

# which tar
/usr/bin/tar

So using this crontab file my /home directory will be backed up to a file named slash media /media/usb/home_bak.tar at 11:05 am of every day of the month on Monday through Saturday.

Predefined Crontab Syntax:

  • @yearly (or @annually) – Run the specified task once a year at midnight (12:00 am) of the 1st of January. Equivalent to 0 0 1 1 *.
  • @monthly – Run the specified task once a month at midnight on the first day of the month. Equivalent to 0 0 1 * *.
  • @weekly – Run the specified task once a week at midnight on Sunday. Equivalent to 0 0 * * 0.
  • @daily – Run the specified task once a day at midnight. Equivalent to 0 0 * * *.
  • @hourly – Run the specified task once an hour at the beginning of the hour. Equivalent to 0 * * * *.
  • @reboot – Run the specified task at the system startup (boot-time).

Source: linuxize.com

Individual User Cron Jobs

Now in addition to creating system cron jobs individual users on your Linux system can also create their own cron jobs running commands on the schedule that they specify and this is done by using a separate crontab file that’s associated with just their user account.

Now unlike the system crontab file which is saved in the /etc directory user crontab files are created and stored in a different directory, they’re stored in /var/spool/cron/.

So if an individual user on your system has created their own crontab file it’ll be saved in the /var/spool/cron/ directory under his or her username.

Note:

Users’ crontab files are named according to the user’s name, and their location varies by operating systems.

  • Red Hat & CentOS: Crontab files are stored in the /var/spool/cron directory
  • Debian & Ubuntu: Files are stored in the /var/spool/cron/crontabs directory

Crontab Security

Now before proceeding I should point out that not all Linux system administrators actually want to allow their users to create their own cron jobs.

Some will have no problem with it whatsoever others will say oh no we don’t allow that.

So, if allowing users to create their own crontab files, their own programs on a particular schedule makes you a bit nervous, you can lock the system down to prevent them from doing this.

The cron daemon will use the two files that you see here:

  • /etc/cron.allow
  • /etc/cron.deny

Both in the /etc directory to determine who can and who cannot create crontab schedules.

Now be aware that by default /etc/cron.allow file does not exist, the only file that exists when the system is initially set up is the /etc/cron.deny file.

If you use just /etc/cron.deny then everybody on the system, all users on the system will be allowed to create cron jobs except for anyone whose account is listed in the /etc/cron.deny file.

Now that’s one way to approach cron security, another approach is to go ahead and create a /etc/cron.allow file in the /etc directory.

If you do this everything changes, basically if /etc/cron.allow exists then /etc/cron.deny is not even used.

If /etc/cron.allow exists, then no users on the system are allowed to create crontab files except for those listed in /etc/cron.allow file.

How users can create their own Crontab Files

So, with this in mind let’s take a look at how users can create their own crontab files.

In order to do this, they login as themselves, in this example I’m logged in as the helpdesk user and then type the crontab -e command.

When you run crontab -e what it actually does is load the vi editor and it creates a new blank crontab file and loads it in the text editor.

And then within this file the user adds lines for each cron job they want to run, and it uses exactly the same syntax as we saw before for system cron jobs.

$ crontab -e
Cron Job
Cron Job

So, in this example the tar Command is going to be used to back up my Users home directory to a file called myhome.tar and it will be run every day at 5:10 p.m.

Notice once again we specified the full path to the tar command here.

Now once you’re done creating your crontab file you exit out of the vi editor just as you would if you’re editing any other text file and you save it and when you do a new crontab file for your user accounts created in /var/spool/cron/.

And the cron service will be notified that a new crontab file has been created.

So, it actually reloads itself so the new configuration that you specified in the crontab file can be applied.

Now there are a couple of other options you can use with the crontab command.

List user’s crontab

Just to view your users crontab file type the following command.

$ crontab -l
10	17	*	*	*	/bin/tar -cvf ~/myhome.tar ~

Delete user’s crontab

And if for some reason you decide you don’t want a crontab file anymore from my user account you use the -r option with crontab which will remove your users crontab file.

$ crontab -r

$ crontab -l
no crontab for helpdesk

Prompt before deleting

Type the following command to remove your current crontab file with a prompt before removal.

$ crontab -i

Some more examples

1. Schedule the backup script to run every night at 5pm..

$ sudo crontab -e
0 17 * * * /etc/myscripts/backupfiles.sh

2. Schedule the backup script to run at 4am every Friday.

0 4 * * 5 /etc/myscripts/backupfiles.sh

3. Rather than have your special backup script run every Friday, run it on the 20th of every month at 4am.

0 4 20 * * /etc/myscripts/backupfiles.sh

Conclusion

I hope you have learned something from this article and you may have found that crontab is a very important command in Linux.

I have tried my best to include all the features of crontab command in this guide.

Now I’d like to hear your thoughts.

Was this guide useful to you?

Or maybe you have some queries.

Have I not included any command in this guide?

Leave a comment below.

Leave a Comment