If cron is not installed on your system, on a Debian distribution (Ubuntu, Mint), apt-get install can be used to install cron. On a Red Hat distribution (CentOS, Fedora, Red Hat), dnf install or yum install can be used.
dnf install cronie
Before using cron, ensure the cron daemon is enabled and running. The ps command can be used to determine if your system is using init or systemd. If PID 1 is init, then you will use the service command. If PID 1 is systemd, then you will use the systemctl command.
If your system is using systemd, use the systemctl command to start and enable crond.
systemctl start crond
systemctl enable crond
If your system is using init, use the service command to start and enable crond.
service crond start
service crond enable
The crontab -l (list) command can be used to view the entries in your crontab.
crontab -l
The -u option can be used to display a certain users cron table.
crontab -l -u john.doe
In this example, once every minute, the current date and time will be appended to date.log.
AVOID TROUBLE
crontab entries should contain the full absolute path to files
* * * * * echo $(date) >> /home/john.doe/date.log
Something like this could be returned.
00 01 * * * bash /etc/cron.daily/example.sh
If there are no crontab entries, the /var/spool/cron directory will be empty, or the /var/spool/cron/username file will be empty, and be 0 bytes.
~]# ls -l /var/spool/cron
-rw-------. 1 root root 0 Aug 7 21:20 root
On the other hand, if there are crontab entries, the /var/spool/cron/username file can be viewed to view each users cron table.
~]# cat /var/spool/cron/root
00 01 * * * bash /etc/cron.daily/Example.sh
crontab -e (edit) can be used to edit the current users cron table, or the -u option can be included to specify a specifc user. In this example, John Doe's cron table will be edited.
[john.doe@server1 ~]# crontab -e
The @ symbol can be used to run a crontab job hourly, daily, weekly, monthly, or when the server is restarted.
@hourly bash /home/JohnDoe/scripts/Example.sh
@daily bash /home/JohnDoe/scripts/Example.sh
@weekly bash /home/JohnDoe/scripts/Example.sh
@monthly bash /home/JohnDoe/scripts/Example.sh
@reboot bash /home/JohnDoe/scripts/Example.sh
The sleep option can be used to wait a while before running a script after reboot. In this example, Example.sh is run 1 minute after reboot.
@reboot sleep 60 && bash /home/JohnDoe/scripts/Example.sh
Or, you can schedule an exact date and time to reboot.
00 01 * * * /sbin/reboot
You can specify an exact date and time to run a command or script. The syntax of the lines in the cron table is: <minute> <hour> <day of the month> <month> <day of the week> <command or script to execute>. For example, to run Example.sh every day at 1:00 am:
00 01 * * * bash /home/JohnDoe/scripts/Example.sh
Or, to remove every file in the /tmp directory every day at 1:00 am.
00 01 * * * /bin/rm /tmp/*
The first 5 fields of crontab are:
- minute (0-59)
- hour (0-23)
- day of the month (1-31)
- month (1-12)
- day of the week (0-7)
- 0 = Sunday
- 1 = Monday
- 2 = Tuesday
- 3 = Wednesday
- 4 = Thursday
- 5 = Friday
- 6 = Saturday
- 7 = Sunday
Each field can accept a range. For example, to run Example.sh at 1:00 am, Monday through Friday:
00 01 * * 1-5 bash /etc/cron.daily/Example.sh
Fields can also accept a comma separated list. For example, to run Example.sh at 1:00 am on Saturday and Sunday.
00 01 * * sat,sun bash /etc/cron.daily/Example.sh
Intead of sat,sun you could use 6,7.
00 01 * * 6,7 bash /etc/cron.daily/Example.sh
All astericks can be used to run a cron job once every minute.
* * * * * bash /etc/cron.daily/Example.sh
Or, in this example, Example.sh will be run once every 15 minutes, on the hour and then 15 minutes, then 30 minutes, then 45 minutes after the hour.
*/15 * * * * bash /etc/cron.daily/Example.sh
Or, in this example, Example.sh will be run once every 15 minutes as long as minute is 2-59. In other words, Example.sh will not run at 00 or 01 minutes.
2-59/15 * * * * bash /etc/cron.daily/Example.sh
Excluding certain dates / times
You can configure a crontab command to not run using a sort of if/else statement.
* * * * * [ if statement ] || else command
For example, if the content of the foo variable equals the content of the bar variable, then the echo command will be run.
* * * * * if [ $foo == $bar ]; then echo hello >> /tmp/my.log; fi
In this example, if the output of the "$(date +'\%m\%d')" command equals 0101 (January 1st), then the echo command will be invoked.
* * * * * if [ $(date +'\%m\%d') = "0101" ]; then echo "Hello World" >> /home/john.doe/my.log; fi
Or, here is another example. In this example, Hello World will be appended to my.log except for Sunday from 1:00 am to 2:59 am.
* * * * * if [[ $(date +'\%a \%H') !~ (Sun 01|Sun 02) ]]; then echo "Hello World" >> /home/john.doe/my.log; fi
Variables can be defined in the cron table. In this example, the FOO variable contains a value of bar. In this example, bar would be appended to out.txt once every minute.
FOO="bar"
* * * * * echo $FOO >> out.txt
You may need to escape special characters, such as the % characters
@daily cp /usr/local/samba/share/example.db /usr/local/backups/example.db.backup.$(date +\%Y\%m\%d)
I once had a weird issue where the which command on the command line returned /usr/local/bin/aws.
~]# which aws
/usr/local/bin/aws
I had the same which command in a Python script.
aws_cli = subprocess.Popen("which aws", shell=True, stdout=subprocess.PIPE)
If I manually ran the Python script, the which command would return /usr/local/bin/aws. But when I ran the Python script via crontab, the which command was returning /usr/bin/aws.
I resolved this by adding the SHELL and PATH variables to the top of my users crontab. The PATH variable included /usr/local/bin so that the which command would return /usr/local/bin/aws.
PATH=/bin/sh
PATH=/home/john.doe/.local/bin:/home/john.doe/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
By default, cron will send an email to the owner of the cron table after an entry in the users crontab has been executed. MAILTO can be used to send the email to some other receipient.
MAILTO="john.doe@example.com"
Or MAILTO can be empty to not send an email.
MAILTO=""
crontab -r (remove) can be used to remove a users entire cron table.
crontab -r
Cron log
Refer to Linux Files - cron log.
Did you find this article helpful?
If so, consider buying me a coffee over at