How to Schedule Tasks in Linux Systems


To run Linux systems efficiently, especially in a production environment, demands several tasks to run simultaneously, and some at another specified time. These tasks keep the system well maintained and running smoothly. The Linux operating system has built-in commands that can take care of all scheduled tasks. Let’s see what these are.

From time to time, an administrator or end user will want to run a command or series of commands at a set point in the future. Examples include office workers who want to schedule an email to the boss, as well as systems administrators working on firewall configurations who put a ‘safety’ job in place to reset the firewall settings in ten minutes, unless they deactivate the job before that. These scheduled commands are often called tasks or jobs.

Scheduling one-time tasks with the at command

For users of a Red Hat Enterprise Linux (RHEL) system, at is a solution for scheduling future tasks. This is not a standalone tool, but rather a system daemon (atd), with a set of command-line tools to interact with the daemon (at, atq and more). In a default RHEL installation, the atd daemon is installed and enabled automatically. The atd daemon can be found in the at package.

Users (including the root) can queue up jobs for the atd daemon using the at command-line tool. The atd daemon provides 26 queues, a to z, with jobs in alphabetical order; the later queues get less system priority.

Scheduling jobs

A new job can be scheduled by using the command at <TIMESPEC>. at will then read the commands to execute the stdin. For larger commands, and those that are case-sensitive, it is often easier to use input redirection from a script’s file, e.g., at now +5 min <myscript, rather than typing all the commands manually in a terminal window. When entering commands manually, you can finish your input by pressing CTRL+D.

<TIMESPEC> allows for many powerful combinations, giving users an (almost) free-form way of describing exactly when a job should be run. Typically, they start with a time, e.g., 02:00pm, 15:59, or even teatime, followed by an optional date or the number of days in the future.

Some examples of combinations that can be used are listed in the following text. For a complete list, see the timespec definition in the Reference section (see note below).

Note: Reference section for crond includes three man pages – crond(8), crontab(1), crontab(5), which can be opened by the man command in the Red Hat Enterprise Linux 7 section.

now +5min

teatime tomorrow(teatime is 16:00)

noon +4 days

5pm august 3 2016

Inspecting and managing jobs

Inspecting jobs: Running the atq command will give a job scheduled to run in the future, a number, date and time schedule, as well as the queue for the job and its owner.

Note: Normal, unprivileged users can only view and control their own jobs. The root user can view and manage all jobs.

To inspect the actual commands that will run when a job is executed, use the command at-c <JOBNUMBER>. The output will first show the environment for the job being set up to reflect the environment of the user who created the job (at the time this job was created), followed by the commands to be run.

Removing jobs: The command atrm <JOBMUMBER> will remove a scheduled job. This is useful when a job is no longer needed—for example, when a remote firewall configuration has succeeded and does not need to be reset.

Scheduling recurring jobs with Cron: Using at, one could, in theory, schedule a recurring job by having the job resubmit a new job at the end of its execution. In practice, this turns out to be a bad idea. RHEL systems ship with the crond daemon enabled and are started, by default, specifically for recurring jobs. crond is controlled by multiple configuration files, one per user (edited with the crontab (1) command), and system wide files. These configuration files give users and administrators fine-grained control over exactly when their recurring jobs should be executed. The crond daemon is installed as part of the cronie package.

If the commands that run from a cron job produce any output to either stdout or stderr that is not redirected, the crond daemon will attempt to email that output to the user owning that job (unless overridden) using the mail server configured on the system. Depending on the environment, this may need additional configuration.

Scheduling jobs: Normal users can use the crontab command to manage their jobs. This command can be called in four different ways:

crontab –l (List the jobs for the current user).

crontab –r (Remove all jobs for the current users).

crontab –e (Edit jobs for the current user).

crontab <filename> (Remove all jobs, and replace with the jobs read from <filename>. If no file is specified, stdin will be used.

Note: The root can use the option –u <username> to manage the jobs for another user. It is not recommended to use the crontab command to manage system jobs; instead, the methods described in the next section should be used.

Job format

When editing jobs with crontab-e, an editor will be started (vi by default, unless the EDITOR environment variable has been set to something different). The file being edited will have one job per line. Empty lines are allowed, and comments start their line with a hash symbol (#). Environment variables can also be declared, using the format NAME=value, and will affect all lines below the line in which they are declared. Common environment variables in a crontab include SHELL and MAILTO. Setting the SHELL variable will change which shell is used to execute the commands on the lines below it, while setting the MAILTO variable will change which email address output will be mailed to.

Important: Sending emails may require additional configuration of the local mail server or an SMTP relay on a system.

Individual jobs consist of six fields, which detail when and what should be executed. When all five of the first fields match the current date and time, the command in the last field will be executed. The fields are in the following order:







Important: When the ‘Day-of-month’ and ‘Day-of-week’ fields are both other than *, the command will be executed when either of these fields match. This can be used, for example, to run a command on the fifteenth of every month, and on every Friday.

The first five of these fields all use the same syntax rules: * for “Don’t Care”/ always.

There is a number to specify the number of minutes or hours, a date, or a weekday. (For weekdays, 0 equals Sunday, 1 equals Monday, 2 equals Tuesday, etc. 7 also equals Sunday. x-y is used for a range, inclusive of x and y.) x, y for lists: Lists can include ranges as well, e.g., 5, 10-13, 17 in the ‘Minutes’ column, to indicate that a job should run at 5 minutes past the hour, 10 minutes past, 11 minutes past, 12 minutes past, 13 minutes past, and 17 minutes past.

*/x indicates an interval of x, e.g., */7 in the ‘Minutes’ column will run a job in exactly every seven minutes.

Additionally, three-letter English abbreviations can be used for both months and weekdays, e.g., Jan, Feb and Tue, Wed.

The last field contains the command to be executed. This command will be executed by /bin/sh unless a SHELL environment variable has been declared. If the command contains an unescaped percentage sign (%), that sign will be treated as a new line, and everything after the percentage sign will be fed to the command or stdin.

Examples of cron jobs:

Start the crontab editor:

# crontab –e

Insert the following line:

* * * * * * date >> /home/student/my_first_cron_job.

Save your changes and quit the editor.

Inspect all of your scheduled cron jobs.

# crontab –l

Wait for your job to run, the inspect the contents of the /home/student/my_first_cron_job.

# cat ~/my_first_cron_job.

Remove all of the cron jobs for student.

# crontab –r.

Scheduling system cron jobs

System cron jobs: Apart from user cron jobs, there are also system cron jobs. System cron jobs are not defined using the crontab command, but are instead configured in a set of configuration files. The main difference in these configuration files is an extra field, located between the Day-of-week field and the Command field, specifying under which user a job should be run.

System cron jobs are defined in two locations: /etc/crontab and /etc/cron.d/*. Packages that install cron jobs should do so by placing a file in /etc/cron.d/, but administrators can also use this location to more easily group related jobs into a single file, or to push jobs using a configuration management system.

There are also predefined jobs that run every hour, day, week and month. These jobs will execute all scripts placed in /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, and /etc/cron.monthly/, respectively. Do note that these directories contain executable scripts, and not cron configuration files.

Important: Make sure that any scripts you place in these directories are made executable. If not (e.g., with chmod+x), the task will not run as per the schedule.

The /etc/cron.hourly/* scripts are executed using the run-parts command, from a job defined in /etc/cron.d/0hourly. The daily, weekly and monthly jobs are also executed using the run-parts command, but from a different configuration file: /etc/anacrontab.

In the past, /etc/anacrontab was handled by a separate daemon (anacron), but in Red Hat Enterprise Linux 7, the file is parsed by the regular crond daemon. The purpose of this file is to make sure that important jobs will always be run, and not skipped accidentally because the system was turned off or hibernating when the job ought to have been executed.

The syntax of /etc/anacrontab is different from the other cron configuration files. It contains exactly four fields per line:

Period in days

Once per how many days this job should be run

Delay in minutes

The amount of time the cron daemon should wait before starting this job

Job Identifier

This is the name of the file in /var/spool/anacron/ that will be used to check if this job has run. When cron starts a job from /etc/anacrontab, it will update the timestamp on this file. The same timestamp is used to check when a job has last run in the past.

Command: This is the command to be executed. /etc/anacrontab also contains environment variable declarations using the syntax NAME=value. Of special interest is START_HOURS_RANGE. Jobs will not be started outside of this range.

Managing temporary files with system-tmpfiles

A modern system requires a large number of temporary files and directories. Not just the highly visible ones such as /tmp that get used and abused by regular users but also more task-specific ones such as daemon- and user-specific volatile directories under /run. In this context, ‘volatile’ means that the file system storing these files only exists in memory. When the system reboots or loses power, all the contents of volatile storage will be gone.

To keep a system running cleanly, it is necessary for these directories and files to be created when they do not exist (since daemons and scripts might rely on them being there), and for old files to be purged so that they do not fill up disk space or provide fault-configured directories.

In RHEL 7, systemd provides a more structured and configurable method to manage temporary directories and files: system-tmpfiles.

When the system starts, one of the first service units launched is system-tmpfiles-setup. This service runs the command system-tmpfiles –create –remove. This command reads configuration files from /usr/lib/tmpfiles.d/*.conf, /run/tmpfiles.d/*.conf, and /etc/tmpfiles.d/*.conf. Any files and directories marked for deletion in those configuration files will be removed, and any files and directories marked for creation (or permission fixes) will be created with the correct permissions, if necessary.

Regular checking

To make sure that long running systems do not fill up their disks with stale data, there is also a sytemd timer unit that calls system-tmpfiles –clean at a regular interval.

systemd timer units are a special type of systemd service that have a {TIMER} block indicating how often the service with the same name should be started.

On a RHEL 7 system, the configuration for the systemd-tmpfiles-clean.timer units looks like what is shown below:




This indicates that the service with the same name (systemd-tmpfiles-clean.service) will be started 15 minutes after systemd has started and then once every 24 hours, afterwards.

The command systemd-tmpfiles –clean parses the same configuration files as systemd-tmpfiles –create, but instead of creating files and directories, it will purge all files that have not been accessed, changed or modified till the maximum age defined in the configuration file.


Please enter your comment!
Please enter your name here