Did you know that Blade Runner is set in 2019? That’s three years from now! Not to mention Back to the Future 2, where they time-travel forward into 2015. Yet we don’t have flying cars and there are no replicants among us (as far as I know).
It’s easy to feel disappointed with current technology when we compare it to fictional depictions of the future. Still, these days our phones, computers, and even houses can do amazing things. The ability to automate tasks is one of them.
Every Linux user can benefit from scheduling tasks, whether they’re system-related (like cleaning up old logs and updating packages) or serving the user (checking email, downloading podcasts…). Windows users have had Task Scheduler since Windows 95. The utility that does the same job on Linux is called cron, and here we’ll explain how to use it.
What Is Cron?
Cron is a system service that runs in the background, checks for scheduled tasks, and executes them if it finds any. The tasks — also called “cron jobs” — are defined in special configuration files (crontabs), which cron scans every minute. Several versions of cron can be found across on different Linux distributions. For example, Fedora’s fork of cron is called cronie, and there are also fcron, bcron, and dcron. Some have extra features, while others are more focused on security, but they’re all based on the same idea.
This guide is written for vixie-cron, which is the most widespread version of cron and the one you’ll find on Ubuntu and its derivatives. While most instructions apply to other cron implementations too, there might be minor differences, so check their manuals if you decide to switch.
What Is a Crontab?
If you’re serious about managing your time, you probably have a calendar of some sort — an app or at least a piece of paper. Crontab is very much like your computer’s calendar. It holds the information about scheduled tasks, telling cron which commands to run at what time.
In fact, several crontabs are on your system. Every user has their own crontab, including root (the administrator). User crontabs are stored in
crontab -l command will list the crontab file for the current user. You can check the root crontab with
sudo crontab -l.
Additionally, there’s the system crontab file
/etc/crontab which is used for system-wide tasks. Usually, they take the form of executable, root-owned scripts placed in
/etc/cron.monthly/ folders, and on some distributions, the
/etc/cron.d/ folder as well. Generally speaking, you shouldn’t have to deal with these tasks, as most of them are created automatically by installed applications.
How to Schedule Tasks with Cron
It sounds simple: to schedule tasks, just add them to your crontab. Since crontab is a special configuration file, it’s not recommended to edit it manually. Instead, use the
crontab -e command. To edit root or other users’ crontabs, run the command with administrative privileges and add their username after the -u option:
sudo crontab -u root -e
sudo crontab -u username -e
The crontab file has two sections. The first one contains environment variables that are set up automatically. You can safely change the PATH, HOME, and SHELL variables, and modify the MAIL variable.
The second part of the file is the actual “timetable” with your scheduled tasks. Every task occupies a line (row) in the table, with columns representing the following values:
To successfully schedule tasks, you need to know a bit about the crontab syntax:
- The numbers should be integers (whole numbers), and you can use the asterisk (*) in any of the columns as a wildcard, meaning “every minute/day/month…”.
- In the “Day of Month” column, be careful not to set a date that doesn’t occur in the month specified in the “Month” column (for example, 30th of February).
- Both “Month” and “Day of Week” columns accept short names for months and days, respectively, and they’re case insensitive.
- In the “Day of Week” column, both 0 and 7 stand for Sunday. The “Hour” column requires the “military time” (24-hour) format, but you can’t use the number 24 — instead, 0 stands for 12 a.m. This is because the values for minute, hour and day of week start at 0 instead of 1.
- Seconds are not supported, so you can’t schedule a task at a particular second.
What you can do is schedule inclusive time ranges using a hyphen (14-22 under “Hours” will run the task continuously from 2 p.m. to 10 p.m.), or run a single task several times by defining a comma-separated list (1,3,5 under “Day of Week” will run the task on Monday, Wednesday, and Friday).
Meanwhile, step values, are represented by a forward slash (/), and these indicate the amount of skips within a range; for instance, 3-20/3 under “Hours” will run the task every three hours from 3 a.m. to 8 p.m. This is useful when you want to repeat tasks every X hours, because you can combine an asterisk and a step (*/X). You can combine ranges with lists and steps with ranges as long as you’re using numbers. In other words, combinations like “jan-mar” or “Tue,Fri-Sun” are not allowed.
Alternatively, instead of setting a value for every column, you can just write @weekly, @yearly, @monthly, @daily, or @hourly at the beginning of a row, followed by a command. Scheduled like this, the tasks will run at the first possible instance, so @weekly would run at midnight on the first day of the week. If you want to run a task immediately when the system (re)starts, use the @reboot command.
In this example, we’ve scheduled a backup every day at 08:20 and 20:20. The wallpaper changes automatically every three days at 19:00, and a script will check for new podcasts every Monday at 10:20 and 20:20. A birthday reminder is set for March 25 and it runs every 30 minutes within the specified time-frame. Finally, a script checks email every 15 minutes from 8 to 20, but only on workdays. You’re free to organize your crontab with spaces and tabs between columns, but not within them (don’t put spaces between commas, hyphens, and slashes).
If all this sounds too complicated, don’t worry — you can always rely on the internet. Tools like Crontab Generator, Crontab.guru, and Corntab help you create cron jobs without knowing any crontab syntax. They show you when the job will run next, and provide templates for commonly used expressions. Crontab.guru is the best of the bunch because it lets you live-test crontab syntax, so you can immediately see how your changes will affect the schedule.
How to Check If Cron Jobs Are Executed
Cron is supposed to run quietly in the background and let you work undisturbed while it takes care of your tasks. But how can you make sure it’s actually working?
Cron has an in-built email notification feature, but this requires setting up at least a simple local mail server. Not many home users are willing to configure this, and not many distributions provide it by default (for instance, Ubuntu doesn’t). The fastest way to check up on cron is to scan the system log with this command:
cat /var/log/syslog | grep -i cron
The -i option makes our query case-insensitive. It’s possible that cron will have its own log file somewhere in
/var/log/, so look there if this command fails to produce useful results.
If you need to save the output of a particular cron job, you can redirect it to a file. Provide the path and the name of the file in the last column of your crontab, after the command you want to run:
30 * * * * /usr/bin/yourcommand > /home/username/logfile.txt
Using a single > symbol will overwrite the file each time the command runs. To avoid this, use >> instead — it appends the output to the existing file.
What If Cron Isn’t Working?
It might happen that you’ve added some tasks, checked the system logs, and found that they’re not executing as they should. Here are some things you should consider — and be careful about — when trying to fix the problem.
Is the cron service running?
As you know, the cron daemon should be running in the background. Make sure this really is the case. The service is either called crond or just cron.
For distributions using systemd:
systemctl status cron
For distributions using Upstart:
service cron status
If your distribution is using the “old” System V init approach, list all services with:
and see if cron is listed.
Are you even allowed to have a crontab file?
/etc folder for files named
cron.deny. On Ubuntu, neither should exist, which means all users are allowed to manage cron jobs. However, if there is a
cron.allow file, it has to contain your username. Conversely, if the
cron.deny file exists, your username should not be in it. Leaving the
cron.deny file blank means that only root and users listed in
cron.allow can have crontab files.
Are your variables set properly?
Crontab automatically sets your SHELL variable to
/bin/sh. However, if your shell of choice is fish or bash, you should change the SHELL variable
. Likewise, the PATH variable contains only a few directories by default. This is where crontab looks for Linux commands. If your cron job is failing to run, it might be because crontab doesn’t “see” the command you’ve used. To avoid this, add directories containing the commands to the PATH variable, separated by colons:
If you don’t want to edit this in your crontab, you can define these variables in the script you want to run as a cron job.
Is your crontab formatting on point?
Crontab syntax is not exactly smooth sailing. Even if you verify it with online tools mentioned previously, a minor mistake could still prevent cron from executing your jobs. Be careful to:
- add an empty line at the end of the crontab file
- escape the % sign with a backslash if your command includes it
- write comments as separate lines starting with #. Don’t write comments on the same line as the environment variables, or next to cron job commands.
Do You Really Have to Use the Terminal?
Absolutely not. KDE users can schedule cron jobs with KCron, which is accessible from the System Settings > Task Scheduler module. With a straightforward interface that lets you choose and tweak everything in just a few mouse-clicks, KCron is a pleasure to use.
If you prefer GNOME, then GNOME Schedule is for you. The approach is similar, although the interface is, expectedly, slightly different. It offers an advanced mode for fine-grained modifications, and comes with a panel applet from which you can manage tasks directly.
You should be aware of other solutions, like Crontab-UI and Minicron. They’re more suitable for users who manage multiple machines and cron jobs, and one of their coolest features is the web-based interface.
Are There Any Cron Alternatives?
While cron is pretty much the standard task scheduler for Linux, it certainly isn’t the only one. The at command is perfect for quick, one-time jobs that can be scheduled right from the command-line, without special configuration files. If you need more, there is GNUbatch, which introduces the notion of dependency. With GNUbatch, you can set specific conditions for every job, or make a scheduled task depend on a previous one. Something similar can be achieved with systemd timers. Although less practical to configure than cron, systemd timers can remember if a task missed its schedule while the computer was off, and run it the next time it’s on.
This is something that cron cannot do alone. As such, it’s suitable for servers and computers that are constantly running, but it won’t execute a job that was scheduled while the computer was off. This is where anacron comes into play. It’s technically not an “alternative” or a replacement for cron. Instead, anacron complements cron and should be used alongside it, which is the case on many Linux distributions, including Ubuntu and Ubuntu-based products. Anacron logs when a task was last executed, and checks if there were any missed instances while the system was powered off. It will run them when you turn the computer back on, but every task can be executed just once per day.
Some versions of cron, like fcron, offer anacron’s features by default. Advanced users might want to look at Hcron or SuperCron, which bring many improvements to basic cron functions, but are also somewhat challenging to manage.
What about you? How do you organize your digital tasks? Which tasks do you schedule on Linux? Share your stories and tips for using cron in the comments.
Image Credit: schedule board by Gonzalo Aragon via Shutterstock