If you need to perform an action at a specified time on a Unix or Linux server, then you need crontab, also referred to as cronjobs or simply cron. We use crontab for lots of automated tasks throughout the day and thought we would share some of the most common questions we get asked and answers we give – bear in mind this isn’t an all encompassing introduction to crontab, but more of an explanation of common tricks you might need when you already have a basic understanding.
First it’s probably worth covering off a few basic things about how to add a job to the crontab – we will reference the ways to do it on an Amazon EC2 instance running Amazon Linux AMI, but they are very similar across different Linux server installs:
Basic crontab tricks and tips
- Crontab can have issues with running on usernames with an underscore in them – which will be an issue if you are using the default username of ec2_user that Amazon assigns. To avoid any potential hiccups type:
This will log you in as the root user and you can then create your cronjobs from there. Make sure to enter the password for the root user if prompted
- You can edit your crontab by typing:
This will open the crontab file in the default editor (usually VI) without having to go searching through the filesystem for it, and if you don’t have one already it will set it all up for you.
- The basic crontab format is as follows:
Minute | Hour | Day | Month | DayOfWeek | Command
So if you wanted to test the most basic of cronjobs you could perform a directory listing of the /etc directory every minute of every day with the following command:
* * * * * ls /etc
- Want to email the output of the cronjob to a certain single email address easily? Just add the following line above the cronjob in question:
- Want to see a log of what the crontab is doing in order to debug any potential issues? Just use the following command. It will show the last few lines of the log and update if a cron runs again while it is open. To quit out of it just press CTRL and C together:
tail -f /var/log/cron
Running Crontab every 2 hours between 9-5
One of the most common things we are asked is how to run a cronjob every two hours between a certain time frame and it isn’t so clear from the information currently available so we will explain it here as simply as possible. The command you will need is:
00 9-17/2 * * * ls /etc
This will run our command to list the contents of the /etc directory every two hours between 9am and 5 pm. Below is an explanation of the command in more detail:
- 00: This is the minute of the hour to run the job – in this case 00 in every qualifying time period
- 9-17/2: This is the complex part that trips people up. The 9-17 tells this command to run between 9am and 5pm on a 24 hour clock (hence 17) and the /2 ensures that the script only runs every second hour.
- *: Ensures this runs every day.
- *: Ensures this runs every week.
- *: Ensures this runs evey day of the week – If you only wanted this to run on weekdays you could change this to 1-5.
- ls /etc: Lists the contents of the etc directory – the command we want to run – obviously you will probably want to run something more useful!
Sending cronjob output to multiple email addresses
Another issue people face is sending the output of a cronjob to multiple email addresses. Often people will tell you to edit the MAILTO command described above to include each email address separated by a comma, however this is flakey at best and will often result in the cron failing with an UNSAFE message in the log file. The best way to achieve this is to edit your email aliases file, which is actually very simple to do:
- If you are running your crontab as the root user as suggested, you should see a line at the bottom of this file that defines the root alias. Change it as follows:
- The output will now be sent to all three email addresses.
- If you are running your crontab as a different user, just enter a new line at the bottom of the file with the username you are running it as before the colon. Don’t forget to check your crontab afterwards to ensure you aren’t overriding this with a MAILTO command.