5 Automating System Tasks

You can automate tasks to perform periodic backups, monitor the system, run custom scripts, and other administrative tasks. In Oracle Linux, the two utilities that are used for job scheduling are cron and anacron. Both tools enable you to automate the running of tasks, also referred to as jobs, but slightly differ in how the tasks are run. Both utilities automatically run through their respective daemons, and so, you don't need to run these utilities manually.

You can also use systemd timer unit files for scheduling tasks. All the utilities described in this document for task automation can work in combination.

Working With cron

With cron, you can schedule jobs to run as often as every minute. System cron jobs are defined in the cron table called /etc/crontab or in files in the /etc/cron.d directory. User defined jobs are stored in the /var/spool/cron directory and are named after their users, for example, /var/spool/cron/jsmith. The crond daemon, which uses the cron utility to run scheduled jobs, looks in these locations to decide which jobs need to be run.

If the daemon identifies a job that was configured to run in the current minute, then the crond daemon runs that job as the owner of the job definition. If the job is a system cron job, then the daemon runs the job as the user that's specified in the job definition, if the user is defined.

If the system is down when a job is scheduled to run, then when the system is restarted, the daemon bypasses that job until the job's next scheduled run.

For a tutorial on how to work with the cron utility, see Use the Crontab Utility to Schedule Tasks on Oracle Linux.

About the cron Table Fields

The contents of /etc/crontab typically consist of definitions for the SHELL, PATH, MAILTO, and HOME variables for the environment in which the jobs run. These definitions are then followed by the job definitions themselves. Comment lines start with a # character.

A /etc/crontab file without any configured job appears as follows:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# 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

Job definitions consist of information that you specify in the appropriate fields as follows:

minute

Specify a value of 0-59.

hour

Specify a value of 0-23.

day

Specify a value of 1-31.

month

Specify a value of 1-12 or jan, feb,..., dec.

day-of-week

Specify a value of 0-7 (Sunday is 0 or 7) or sun, mon,...,sat.

user

Specify the user running the command; or, you can specify an asterisk (*), which indicates the owner of the crontab file.

command

Specify the shell script or command to be run.

For the minute through day-of week fields, you can use the following special characters:

*

Specify an asterisk (*) for all of the valid values for the field.

-

Specify a dash (-) to indicate a range of integers, for example, 1-5.

,

Specify a list of values, separated by commands (,), for example, 0,2,4.

/

Specify a step value by using the slash (/), for example, /3 in the hour field. This entry is interpreted as every three hours.

For example, the following entry would run a command every five minutes on weekdays:

0-59/5  *  *  *  1-5  *  command               

Run a command at one minute past midnight on the first day of the months April, June, September, and November:

1  0  1  4,6,9,11  *  *  command               

Note:

If you add an executable job script to the /etc/cron.hourly directory, crond runs the script every hour.

All jobs in the /etc/crontab file are run as root.

For more information, see the crontab(5) manual page.

Creating a cron Job

Any user can create a cron job, but the location of the job definition depends on the user's privileges.

  • An administrator who signs in as root creates jobs that are stored in /etc/crontab. Jobs in /etc/crontab are run as root, unless the job definition specifies a different user.

  • A user with administrator privileges can create cron jobs. The jobs are stored in /etc/crontab.d/ and named after the administrator's username.

  • A regular can create jobs which are stored in /etc/crontab.d/. The job file is based after the user's name.

To create or edit a crontab file as a user, such as jsmith, do the following:

  1. Sign in to the system as that user, for example jsmith.

  2. Edit crontab with a text editor.

    crontab -e

    If you want to use a specific text editor to create or edit a cron job, use the following syntax:

    env EDITOR=text-editor crontab -e
  3. When the editor opens, create the cron job by using the format as described in About the cron Table Fields.

    Suppose that you want to define a backup job that you want to run every 15 minutes. Further, you created a script mybackup.sh for this task in the user home directory. You would then create the schedule as follows:

    15 * * * * /home/jsmith/mybackup.sh
  4. Save the file and exit.

    The file is saved as /var/spool/cron/jsmith.

  5. View and verify the contents of the new cron job.

    crontab -l
    15 * * * * /home/jsmith/mybackup.sh

To delete the user crontab file, type:

crontab -r 

For more information, see the crontab(5) manual page.

Controlling Access to Running cron Jobs

The following files, each of which contains usernames, manage access control for running cron jobs:

  • /etc/cron.allow contains the list of users who are permitted to run cron jobs.
  • /etc/cron.deny contains the list of users who are not permitted to run cron jobs.

If both files exist, then /etc/cron.allow takes precedence. Users in this list are permitted to run cron jobs, and /etc/cron.deny is ignored. If only /etc/cron.deny exists, then only those users that are not on this list can run cron jobs.

If none of these two files exists, then only root can run cron jobs.

Configuring anacron Jobs

The anacron utility differs with the cron utility in that anacron limits the number of times a scheduled job can be run to only daily. The anacron utility is mainly intended for use on laptop computers.

If anacron is not already running and the system is connected to mains and not battery power, crond starts anacron.

The crond daemon runs the /etc/cron.hourly/0anacron script as root each hour according to the schedule in /etc/cron.d/0hourly, which has the following job definition:

# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

Then, based on the configuration settings in /etc/anacrontab, the 0anacron script processes the contents in the /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly directories.

If a scheduled job hasn't been run because of system downtime, then that job runs when the system restarts.

System anacron jobs are defined in /etc/anacrontab as follows:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days  delay in minutes  job-identifier   command
1                5	             cron.daily       nice run-parts /etc/cron.daily
7                25	            cron.weekly      nice run-parts /etc/cron.weekly
@monthly         45	            cron.monthly     nice run-parts /etc/cron.monthly

The top of the file contains definitions for the SHELL, PATH, MAILTO, RANDOM_DELAY, and START_HOURS_RANGE variables for the environment in which the jobs run, followed by the job definitions themselves. Comment lines start with a # character.

RANDOM_DELAY is the maximum number of random time in minutes that anacron adds to the delay parameter for a job. The default minimum delay is 6 minutes. The random offset is intended to prevent anacron overloading the system with too many jobs at the same time.

START_HOURS_RANGE is the time range of hours during the day when anacron can run scheduled jobs.

The bottom part of the file contains job definitions. Each job consists of entries that are spread across 4 columns under the following headings:

period

Frequency of job execution specified in days or as @daily, @weekly, or @monthly for daily, weekly, or monthly.

delay

Number of minutes to wait before running a job.

job-id

Unique name for the job in log files.

command

The shell script or command to be run.

By default, anacron runs jobs between 03:00 and 22:00 and delays jobs by between 11 and 50 minutes. The job scripts in /etc/cron.daily run between 03:11 and 03:50 every day if the system is running, or after the system is booted and the time is earlier than 22:00. The run-parts script sequentially runs every program within the directory specified as its argument.

Scripts in /etc/cron.weekly run weekly with a delay offset of between 31 and 70 minutes.

Scripts in /etc/cron.monthly run monthly with a delay offset of between 51 and 90 minutes.

For more information, see the anacron(8) and anacrontab(5) manual pages.

Running One-Time Tasks

Through the atd service, you can use certain commands to schedule one-time tasks.

This section describes the use of the at and batch commands for this purpose. Before you can use these commands, ensure that the at service is running.

sudo systemctl is-active atd
  • To schedule a task to run one time only at a specified tine, use the at command.

    Suppose that you have defined a job in ~/atjob. To schedule that job in 20 minutes time, you would type:

    at now + 20 minutes < ~/atjob
    job 1 at 2021-03-19 11:25
  • To schedule a batch job to run when the system load average is light, use the batch command.

    Suppose that you have defined a batch job in ~/batchjob. To schedule this job to run if the system load average is less than 0.8, you would type:

    sudo batch < batchjob
    job 2 at 2013-03-19 11:31

    Note:

    The system load average threshold under which you can schedule user-defined batch jobs to run is 0.8, by default. However, that value can vary. See Changing the Behavior of Batch Jobs.

  • To list all the scheduled one-time jobs that are in queue, type:

    sudo atq
    job 1 at 2021-03-19 11:25
    job 2 at 2013-03-19 11:31
  • To cancel one or more queued jobs, specify their job numbers to the atrm command, for example:

    sudo atrm 2

For more information, see the at(1) manual page.

Changing the Behavior of Batch Jobs

The system load average represents the average number of processes that are queued to run on the CPUs or CPU cores over time. Typically, a system might not be considered overloaded until the load average exceeds 0.8 times the number of CPUs or CPU cores. On such systems, you might want atd to run batch jobs when the load average drops to less than the number of CPUs or CPU cores, rather than the default limit of 0.8. For example, on a system with 4 CPU cores, you could set the load-average limit over which atd can't run batch jobs to 3.2.

If you know that a batch job typically takes more than a minute to run, you can also change the minimum interval that atd waits between starting batch jobs. The default minimum interval is 60 seconds.

For more information about monitoring CPU usage and to display the system load average, see Monitoring CPU Usage.

To change the load-average limit and minimum interval time for batch jobs:

  1. Open the /etc/sysconfig/atd configuration file with a text editor.
  2. Uncomment the line that defines the OPTS variable.

  3. Provide new values for the load average limit and the minimum interval time to the OPTS variable, for example:

    OPTS="-b 100 -l 3"

    This example sets the minimum interval to 100 seconds and the load-average limit to 3.

  4. Restart the atd service:

    sudo systemctl restart atd
  5. Verify that the atd daemon is running with the new minimum interval and load-average limit, for example:

    sudo systemctl status atd
    atd.service - Job spooling tools
       Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled)
       Active: active (running) since Mon 2014-04-28 15:37:04 BST; 2min 53s ago
     Main PID: 6731 (atd)
       CGroup: /system.slice/atd.service
               └─6731 /usr/sbin/atd -f -b 100 -l 3
    
    Apr 28 15:37:04 localhost.localdomain systemd[1]: Started Job spooling tools.

For more information, see the systemctl(1) and atd(8) manual pages.

Working With Systemd Timers

Timer unit files are a type of systemd file that the systemctl utility uses to schedule tasks, similar to the cron utility that uses crontab and other cron jobs for the same purpose.

Typically, packages that use specific services to function in the system include their own systemd timer unit files. Thus, when these packages are installed with Oracle Linux, the timer unit files are automatically included. You can display with the timer files in the system with the following command:

systemctl list-unit-files --type=timer

Note:

The list of timer files might differ depending on where Oracle Linux is running, such as in an instance in Oracle Cloud Infrastructure, a physical system, and so on.

Each timer unit file contains parameter settings that manage the schedule of a task. For example, the schedule for running dnf-makecache.service is set in the dnf-makecache.timer file. The file contains the following settings:

systemctl cat dnf-makecache.timer
# /usr/lib/systemd/system/dnf-makecache.timer
[Unit]
Description=dnf makecache --timer
ConditionKernelCommandLine=!rd.live.image
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
Wants=network-online.target

[Timer]
OnBootSec=10min
OnUnitInactiveSec=1h
RandomizedDelaySec=60m
Unit=dnf-makecache.service

[Install]
WantedBy=timers.target

The schedule information is specified under the [Timer] section. In the sample configuration, the dnf-makecache.service service is set to automatically run 10 minutes after the system is booted. The service then goes into idle mode for an hour, as specified by the OnUnitInactiveSec parameter. At the end of the hour, the service runs again. This cycle continues every hour indefinitely.

The RandomizedDelaySec setting provides a value limit for how much a run can be delayed beyond its schedule. In the example, the service is allowed to run one minute later than its schedule at the latest. This parameter is useful for preventing too many jobs that start at the same time on a specified schedule, which would otherwise risk overloading the resources.

OnCalendar is another useful parameter for task scheduling. Suppose that the parameter is set as follows:

OnCalendar=*:00/10

The *:00 indicates every hour at the top of the hour, while the /10 setting indicates 10 minutes. Therefore, the job is set to run hourly, at ten minutes past the top of the hour.

For a complete list of systemd timer unit file parameters for scheduling a job, see the systemd.timer(5) manual pages.

For a tutorial on how to use systemd in Oracle Linux, including how to configure systemd timer unit files, see Use systemd on Oracle Linux.