Cron on Unix

I am going to be a moderator for a CS course this coming semester! As part of that job, I will have to grade assignment submissions from the GitHub repo of all the students. Additionally I will have to ensure that I only pull the code from Github exactly at the deadline to avoid grading late submissions. Well that is a lot of monotonous, boring and tedious work for each week. :| Well I thought why not automate it! I researched a bit and found that all I needed to do was write a bash script which pulls from all the students repos into the correct directories and all I have to do is run that script at the deadline time. Urgh… but that would mean I will have to set an alarm each week for a particular time to remind me to run the script. What if I forget? A little more research and I learned about this amazing software utility on Unix-like machines called Cron which would automate the task of running the script at a particular time each week! Its powerful, handy and easy to use. You can tweak it to do some pretty cool things so lets learn about it!

What is Cron?

Cron is a time-based job scheduler in Unix-like computer operating systems. You can use cron to schedule tasks like running commands or scripts at regular intervals or fixed times or dates. The name Cron was derived from the Titan named Cronos from the Greek mythology who personifies time. (Rick Riordan’s Percy Jackson series portrays Cronos as evil though :’D )

Cron is majorly used for automation of repetitive tasks. You can use the at command to schedule one time tasks to be executed at a particular time. Some of cron’s common uses are making database backups, downloading mails or other files from internet, running backup scripts, etc.

Under the hood, cron is a daemon. For those of you who don’t know, a daemon is a program which runs as a background process instead of being controlled by the user. Cron is started only once (usually at boot time) and will remain dormant until it is required. Cron is driven by its configuration files called crontab (cron table) files which holds the shell commands to execute at specific times. We will learn the syntax and initiation of crontab in the next section. The cron daemon (crond) wakes up every minute and checks whether any jobs have been scheduled to run during that minute otherwise it lays dormant.

How to use it?

We are going to see how we can configure cron using shell. Unix systems pretty much abstract away much of cron’s functionality from us which makes it really easy to use. Using cron boils down to adding a line to crontab for each job. Crond starts automatically at boot, takes care of all the jobs and does not disturb you pretty much at all. As soon as you modify any crontab and write to the file, crond is notified and everything is taken care of. It really is simple!

Lets see how we can modify our crontab. Each user has their own crontab file and there is a system-wide crontab file which resides somewhere in /etc/ directory which can only be edited by system administrators. Here are a few commands which are used to edit your own crontab file.

crontab -l (Display the current crontab on standard output)crontab -e (Edit the current crontab using the editor specified by      the VISUAL or EDITOR environment variables)crontab -r (Remove the current crontab)

Now lets learn how to use crontab syntax. Wikipedia provides this amazingly concise depiction of the syntax:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute

Cron runs the job when the time/date specification fields all match the current time and date. So to execute a command on the eve of New Years you would use 0 0 1 1 * command to execute.* is a wildcard which stands for all values for that field. So 0 0 1 * * would execute at the beginning of each month throughout the year. There is one exception though. What happens if you specify day of week and day of month (both are not *) and the two fields disagree (that day of month is actually some other day of week)? This is resolved by the following rule: if field 3 and 5 are specified, then one or both must match the current day. So either of them should match along with rest of the fields for the job to execute.

Try it yourself! Lets write a simple cron job which writes your name to a text file on the Desktop every minute. Run the command crontab -e (which by default opens a vi editor) and add the line:

 * * * * * echo your_name > <absolute path to Desktop>/your_name.txt

Replace <absolute path to Desktop> with the output of pwd in Desktop dir. Write the file and wait for the next minute to start to see a text file appear on your Desktop! To see if cron is running in the background, run ps aux | grep cron in shell. You should see the cron process running like this:

root         1023   0.0  0.0  4286472   1272   ??  Ss    5:36PM   0:00.01 /usr/sbin/cron

Pretty cool right! Now do crontab -r to delete the crontab contents because I don’t think you want that text file on your Desktop to reappear each minute! To run more complex tasks, you could write a bash script which performs a bunch of things and all you need to do is run that script in the crontab. If you are not familiar with bash scripting here is an amazing tutorial which I would highly recommend. Bash scripting is an essential and useful skill to have.

Also there are these four important environment variables which you can tweak inside the crontab according to your preference:

Variable     Description
SHELL specifies which shell environment to use
PATH path for execution of specific commands
MAILTO specifies the user who will receive mail if required
HOME home directory for cron job execution

If an error occurs or if there is any message, it will be sent to the MAILTO user. You can check the mail in the /var/mail/ directory which contains the mail files for each user named after their username. The commands specified in crontab will be executed from the directory specified by the HOME variable.

You can also add cron jobs to the system-wide crontab very easily. There is a small difference though. There is an additional field you will have to specify namely the user field (which makes sense since the system has to know for which user to execute this job). This system-wide crontab resides in /etc/crontab and its syntax is:

Min Hr DoM MoN DoW user      command
* * * * * username ________

There is another way of adding cron jobs. You can add the shell script to be executed to either /etc/cron.hourly , /etc/cron.daily , /etc/cron.weekly or /etc/cron.monthly directories for it to be executed hourly, daily, weekly or monthly respectively. The shell scripts contained in these directories will be executed periodically by /etc/crontab with user specified as root. You can confirm this by seeing the default contents of /etc/crontab which would look something like (source):

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

run-parts executes all the scripts inside the directory specified.

However, one of the disadvantages of cron is that your cron jobs would not run if your computer is shut down or asleep. Cron does not handle missed jobs and assumes that the system is running always. If you want your computer to execute all missed jobs, you can look into Anacron which upon boot checks for missed jobs and executes them too. Unlike cron, anacron does not run on the assumption that the system is running continuously. You could also host your cron jobs on your server (if you are using any). Otherwise, there are many tools like cPanel, EasyCron and A2 Hosting which provide online automation tools with a graphical user interface for web hosting.

Hope that gave you some insight into what cron is and how to use it. See you next time!

Computer Science enthusiast. Into software development and data science. Love learning new things and appreciate new ideas. Learn more about me at !