1. Overview

We may use cron as part of our software design and wish to install that software on multiple machines. To produce an installation script, we need to know how to add our cron jobs via a script.

In this tutorial, we’ll look at how to install cron jobs in a couple of places, and how to write scripts to do this for us.

2. Installing a crontab

There are two different crontab files in the system:

  • The user crontab file
  • The system crontab file

The jobs in the user crontab file will only run for the specific user. So, if we need to run the job for all users, we should add that to the system crontab.

2.1. Example Cron Job

Let’s create an example script – job.sh:

#!/bin/bash
echo `date +"%Y-%M-%d %T"`" - Hello Baeldung" >> /home/baeldung/log.txt

We can check log.txt at any time to see whether our scheduled job has run.

2.2. Adding the Job to User crontab

To understand the user crontab, let’s add the script to it manually:

$ crontab -e

This command will open an editor to edit the existing user crontab. Let’s append our cron expression:

30 0 * * * /home/baeldung/job.sh

This schedules the script to run every day, 30 minutes after midnight. We’ve created the job in our home directory – /home/baeldung.

We also need to be sure that the current user has execute permissions for this script. So, let’s use the chmod command to add them:

$ chmod +x /home/baeldung/job.sh

Now our job.sh is scheduled and will run every day. We can test this by inspecting the log.txt file.

2.3. Adding the Job to System crontab

To understand the system crontab, let’s also add this script to it manually:

$ sudo nano /etc/crontab

The system crontab file is kept in /etc/crontab. Let’s append the following line:

30 0 * * * root /home/baeldung/job.sh

We should note that we need to specify the root username. This is because jobs in system cron are system jobs and will be run by the root user.

3. Script for Adding the Job to User crontab

Now let’s try automating the process to add to the user crontab.

3.1. Install a New File to crontab

Let’s first create a new script file:

$ touch /home/baeldung/myScript.sh

The first thing our script will do is take a copy of all the current jobs:

#!/bin/bash
crontab -l > crontab_new 

We now have all the previous jobs in the crontab_new file. This means we can append our new job to it and then rewrite the crontab by using the edited file as an input argument to the crontab command:

echo "30 0 * * * /home/baeldung/job.sh" >> crontab_new
crontab crontab_new

Since the crontab_new file is temporary, we can remove it:

rm crontab_new

We must also remember to use chmod +x to make the script executable:

$ chmod +x /home/baeldung/myScript.sh
$ ./myScript.sh

This method works well, though it does require the use of a temporary file. Let’s see if we can optimize it further.

3.2. Optimize the Previous Script by Using a Pipe

Our previous script relied on a temporary file and had to tidy it up. It also didn’t check whether the cron entry was already installed, and thus, it could install a duplicate entry if run multiple times.

We can address both of these by using a pipe-based script:

#!/bin/bash
(crontab -l; echo "30 0 * * * /home/baeldung/job.sh") | sort -u | crontab -

As before, the crontab -l and echo commands write out the previous lines of the crontab as well as the new entry. These are piped through the sort command to remove duplicate lines*.* The -u option in sort is for keeping only unique lines.

The result of this is piped into the crontab command, which rewrites the crontab file with the new entries.

We should be aware, though, that using sort will completely reorder the file, including any comments. sort -u is pretty easy to understand in a script, but we can achieve a less destructive de-duplication with awk:

#!/bin/bash
(crontab -l; echo "30 0 * * * /home/baeldung/job.sh")|awk '!x[$0]++'|crontab -

This will remove all duplicates from the crontab without sorting it.

4. Script for Adding a Job to System Cron

Let’s now write an installation script for system cron jobs.

4.1. Using System crontab

First, let’s create a new script:

$ touch /home/baeldung/myScript2.sh

The syntax of the system schedule line is similar to the user schedule*.* We just need to specify the root username in the schedule line:

#!/bin/bash
sudo /bin/bash -c 'echo "30 0 * * * root /home/baeldung/job.sh" >> /etc/crontab'

We’re using sudo /bin/bash before echo because the user needs root access to both echo and redirect as the root user. Otherwise, we’ll get a permission denied error because just echo will run by root and the redirection will be made with the current user’s permission. The -c option tells bash to get the command in single quotes as a string and run it in a shell.

We should note that this is plain file manipulation, compared with the crontab command used earlier. We can add similar filters like sort or awk if we want to avoid duplicate entries.

4.2. Using the /etc/cron.d Directory

Besides the /etc/crontab path, cron considers all the files in the /etc/cron.d directory as system jobs, too. So, we can also put the schedule line in a new file in the /etc/cron.d directory.

Let’s now make another script for adding a job to the cron.d directory, as an alternative to the /etc/crontab file:

$ touch /home/baeldung/myScript3.sh

We need to put the schedule line in a new file in the cron.d directory — we’ll call our file schedule. Note that in /etc/cron.d, some filenames are considered invalid**.** For example, if we choose schedule.sh for the filename, it will be skipped because the filename should not have any extension:

#!/bin/bash
sudo touch /etc/cron.d/schedule

The cron.d directory and its sub-directories are usually used by system services, and only the root user can have access to these directories. Also, the files in /etc/cron.d must be owned by root. So, we need to use sudo.

Let’s now put our schedule line in the schedule file and change the permissions:

sudo echo "30 0 * * * root /home/baeldung/job.sh" > /etc/cron.d/schedule
sudo chmod 600 /etc/cron.d/schedule

Note that we change the file’s permissions to 600. This is because files in /etc/cron.d must not be writable by group or other. Otherwise, they will be ignored. Also, the schedule files under /etc/cron.d do not need to be executable. So, we don’t need permission 700.

5. Conclusion

In this article, we discussed different ways of adding jobs to crontab via a script.

We saw how to add jobs to the user and system crontab with both the crontab command and by adding to the files directly using echo.