On our today’s guide, we will focus on how to schedule jobs on Linux with cron and systemd timers. One of the most critical responsibilities of a skilled Linux system administrator is to schedule jobs that must be run on a regular basis. An administrator, for example, can design and automate jobs for backups, system updates, and a variety of other ceaseless tasks. You may accomplish this by using the cron feature, which allows you to schedule jobs on a regular basis.

1. Scheduling jobs on Linux Using cron

Scheduling Jobs with cron

Cron is a daemon in Linux that runs in the background and wakes up every minute to check a set of tables for jobs to complete. The so-called cron jobs are stored in these tables, which are known as crontabs. Because each cron job is only done if the system is operating at the specified time, Cron is ideal for servers and systems that are continuously turned on. Ordinary users, who each have their own crontab, as well as the root user, who maintains the system crontabs, can utilize it.

System Crontabs

The root user can only modify system crontabs, which are text files that govern the scheduling of system cron jobs. System crontabs are /etc/crontab and all files in the /etc/cron.d directory.

Majority of Linux distributions have directories located in /etc directory that contain programs that should be performed on a regular basis. These directories include;

  • /etc/cron.hourly: it contains scripts to be run hourly.
  • /etc/cron.daily: it contains scripts to be run daily.
  • /etc/cron.weekly: it contains scripts to be run weekly.
  • /etc/cron.monthly: it contains scripts to run monthly.

System crontabs have a similar syntax to user crontabs, but they additionally include an extra required column that indicates which user will perform the cron job. As a result, a system crontab line has seven fields separated by a space. These fields include the following;

  • The minute of the hour (0-59).
  • The hour of the day (0-23).
  • The day of the month (1-31).
  • The month of the year (1-12).
  • The day of the week (0-7 with Sunday=0 or Sunday=7).
  • The name of the user account to be used when executing the command.
  • The command to run.

User Crontabs

User crontabs are text files that handle the scheduling of cron tasks that have been established by the user. They are usually called for the user account that created them, although their placement (typically a subfolder of /var/spool/cron) varies depending on the distribution.

A user crontab has six fields separated by a space on each line:

  • The minute of the hour (0-59).
  • The hour of the day (0-23).
  • The day of the month (1-31).
  • The month of the year (1-12).
  • The day of the week (0-7 with Sunday=0 or Sunday=7).
  • The command to run.

Here is a sample of /etc/crontab file in Ubuntu;

$  cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.


# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

In the above output, the first five fields can include one or more values, and they indicate when the command given in the sixth field should be executed. You can use the following syntax to indicate multiple values:

asterisk (*)it refers to any value
slash (/)it specifies stepped values.
comma (,)it specifies a list of possible values.
dash (-)it specifies a range of possible values.

The *, ,, -, and / operators can be used to provide multiple values for the time fields in user crontabs. Instead of using the matching number, you may use the first three letters of the name to indicate the month of the year and the day of the week.

Time Specifications

You may also use custom shortcuts in the first five columns instead of time requirements when modifying crontab files as follow;

Custom ShortcutMeaning
@rebootRunning the specified task once after reboot.
@hourlyRunning the specified task once an hour at the beginning of the hour.
@daily / @midnightRunning the specified task once a day at midnight.
@weeklyRunning the specified task once a week at midnight on Sunday.
@monthlyRunning the specified task once a month at midnight on the first day of the month.
@annualy / @yearlyRunning the specified task once a year at midnight on the 1st of January.

Crontab Variables

Variable assignments are occasionally defined before the scheduled jobs are declared in a crontab file. The following are some of the most often set environment variables:

  • HOME: The directory where the instructions are executed by cron (by default, the user’s home directory).
  • MAILTO: The user’s name or the address to which standard output and errors are sent (by default the crontab owner). An empty value indicates that no mail should be sent, and multiple comma-separated values are also permitted.
  • PATH: This is the location where you may find commands.
  • SHELL: The shell to use (/bin/sh by default).

Creating User Cron Jobs

Individual users’ crontab files are maintained using the crontab command. The crontab -e command, in particular, may be used to modify or create your own crontab file. Let’s look at the example below;


$ crontab -e
no crontab for frank - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        < ‑‑‑‑ easiest
  3. /usr/bin/vim.tiny

Choose 1-3 [2]:

The crontab command opens the editor chosen by the VISUAL or EDITOR environment variables by default, allowing you to begin modifying your crontab file with the editor of your choice. When you run crontab for the first time, some distributions, like the one in the example above, give you the option of selecting an editor from a list.

We can run the following script in the crontab opened above;

0,20,30,40 08 * * 3 /home/frank/updates.sh

The above script is script is executed every Wednesday at 08:00 am, at 08:20 am, at 08:30 am and at 08:40 am.

Other useful crontab options;

  • -l: Print the current crontab to the standard output.
  • -r: Remove the current crontab using.
  • -u: The username of the user whose crontab has to be changed. The root user can edit user crontab files with this option, which requires root capabilities.

Creating System Cron Jobs

System crontabs, unlike user crontabs, are changed with an editor, so you don’t need to use the crontab command to make changes to /etc/crontab and the files in /etc/cron.d. When editing system crontabs, keep in mind that you must provide the account that will perform the cron job (usually the root user).


If you want the foo.sh script in the /root directory to run every day at 03:20 a.m., enter /etc/crontab using your favorite editor and add the following line:

20 03 * * * root /root/foo.sh >>/root/output.log

As shown above, output of the job is appended to /root/output.log.

Access to Job Scheduling

To establish crontab limitations in Linux, use the /etc/cron.allow and /etc/cron.deny files. They’re especially useful for allowing or disallowing the scheduling of cron jobs for distinct users. Only non-root users specified in /etc/cron.allow can use the crontab command to schedule cron tasks if it exists. If /etc/cron.allow is missing but /etc/cron.deny is present, only non-root users specified in this file will not be able to use the crontab command to schedule cron tasks (in this example, an empty /etc/cron.deny indicates that any user will be able to use crontab).

2. Scheduling jobs on Linux using Systemd Timers

You may use timers instead of cron to schedule tasks while using systemd as the system and service manager. Timers are systemd unit files with the .timer suffix, and each one must have a matching unit file that defines the unit that will be triggered when the timer expires. A timer initiates a service with the same name as the timer, except for the suffix.

A [Timer] portion of a timer indicates when scheduled jobs should execute. You may use the OnCalendar= option to create real-time timers that function similarly to cron tasks (they are based on calendar event expressions). The syntax for the OnCalendar= option is as follows:

DayOfWeek Year-Month-Day Hour:Minute:Second


If you want the /etc/systemd/system/bar.service service to start at 07:20 on the first Monday of every month, add the following lines to the /etc/systemd/system/bar.timer unit file.

Description=Run the bar service

OnCalendar=Mon *-*-1..7 07:20:00


After you’ve established the new timer, run the following commands as root to activate and start it:

$ systemctl enable bar.timer

$ systemctl start bar.timer

You may use certain custom expressions to define specific frequencies for task execution instead of the lengthier normalized form stated above:

  • hourly: Once each hour, at the start of the hour, run the given job.
  • daily: Once a day, at midnight, run the given job.
  • weekly: Once a week, at midnight on Monday, run the given job.
  • monthly: Once a month, at midnight on the first day of the month, run the given job.
  • yearly: Once a year, at midnight on January 1st, run the given job.

3. Scheduling jobs on Linux Using at

Scheduling Jobs with at

The at command is used to schedule one-time tasks and simply requires you to provide a future date. After entering at followed by the time specification on the command line, you will be sent to the at prompt, where you may specify the commands to be performed. The Ctrl+D key combination can be used to leave the prompt.


$ at now +2 minutes
warning: commands will be executed using /bin/sh
at> ls /home/frank
at> <EOT>
job 1 at Fri Jul  9 11:50:00 2021

In the example above, the at task simply runs the ls command where it will list the contents of /home/frank directory after two minutes. The usual output and error are emailed to you, just as with cron. Note that in order to use at job scheduling, the atd daemon must be operating on the system.

Useful at command options;

  • -c: Write the job ID’s commands to standard output.
  • -d: Jobs are deleted depending on their job ID. It’s a slang term for atrm.
  • -f: Instead of using the standard input, read the task from a file.
  • -l: Show the user’s pending jobs. All jobs of all users are shown if the user is root. It’s a slang term for atq.
  • -m: Even if there was no output, send mail to the user at the end of the task.
  • -q: Specify a queue as a single letter from a to z, and from A to Z. (by default a for at and b for batch). The niceness of jobs in the queues with the highest letters is enhanced. Batch jobs are jobs that are sent to a queue with a capital letter.
  • -v: Display the time when the job will complete before reading the job.

Listing Scheduled Jobs with atq

You may use the atq command to see a list of your pending jobs, which displays the following information for each job: job ID, job execution date, job execution time, queue, and username.

$ atq
4	Fri Jul  9 12:30:00 2021 a frank
5	Fri Jul  9 12:30:00 2021 a frank
3	Fri Jul  9 19:20:00 2021 a frank

The at -l command is an alias for atq.

Delete Jobs with atrm

The atrm command, followed by the job ID, can be used to remove a job.


To remove the task with ID 5, for example, use the following command;

$ atrm 5

Access to Job Scheduling

The /etc/at.allow and /etc/at.deny files control whether regular users are allowed to schedule jobs. Only non-root users specified in /etc/at.allow can schedule at jobs if it exists. Only non-root users named in /etc/at.deny cannot schedule at tasks if /etc/at.allow does not exist but /etc/at.deny does (in this example, an empty /etc/at.deny file indicates that each user is permitted to schedule at jobs). If neither of these files exist, the user’s ability to schedule jobs is determined by the distribution method employed.

Time Specifications

In the case of a 12-hour format, you can define when a job should be executed using the format HH:MM, optionally followed by AM or PM. If the stated time has past, the next day will be assumed. If you want the task to run on a certain day, use one of the following formats after the time: month-name day-of-month, month-name day-of-month year, MMDDYY, MM/DD/YY, DD.MM.YY, and YYYY-MM-DD).

The keywords midnight, noon, and teatime (4 p.m.) are also acceptable, and are now followed by a plus sign (+) and a time interval (minutes, hours, days and weeks). Finally, by prefixing the time with the phrases today or tomorrow, you can determine whether the work should be completed now or tomorrow. For example, at 11:15 AM Feb 07 can be used to run a job at 11:15 AM on February 7, while at now +5 minutes may be used to run a job five minutes from now. More information on the exact definition of time requirements may be found in the timespec file in the /usr/share directory.

4. Scheduling jobs on Linux using Systemd-run

You may use the systemd-run command to schedule one-time tasks while using systemd as the system and service manager. It’s usually used to make a temporary timer unit so that a command may be run at a particular time without requiring the creation of a service file.


As root, you may use the following command to run the date command at 03:30 PM on 2021/05/10;

$ systemd-run --on-calendar='2021-05-10 15:30' date

After five minutes, you may use: updates.sh to start the script in your current working directory;

$ systemd-run --on-active="5m" ./updates.sh


Up to this far we have concluded our guide on how to schedule jobs on Linux with cron and systemd timers. Thanks for dedicating your time to go through this guide. We hope you have benefited from it. Cheers!

Other Guides;

LPIC 102 – Managing User and Group Accounts on Linux

LPIC 101 – Locating and Finding Files on Linux Filesystems

How To Install GNS3 on macOS Big Sur

Install and Configure Memcached on Debian 10 (Buster)


Please enter your comment!
Please enter your name here