Scheduling with at and cron on RHEL

Reading Time: 4 minutes

When you need to automate tasks on Red Hat Enterprise Linux, you have two go-to tools:

  • at for one-off, one-time jobs.
  • cron (via crontab) for recurring schedules.

The “at” command

at queues single-run jobs to be executed once, at a specified future time.

Key Concepts:

  • Jobs are stored in /var/spool/at (job files) and /var/spool/at/jobs.
  • The atd daemon must be running (systemctl status atd).
  • Each job gets an ID you can list, remove, or view.

Common Subcommands

Schedule a command or script:

echo "/path/to/script.sh" | at 02:30 pm tomorrow

Interactive scheduling:

at now + 1 hour
at> /usr/bin/backup.sh
at> <EOT>     # press Ctrl+D to end

List pending jobs:

atq

Remove a job by its ID:

atrm 5

Time Specifications

You can use a variety of formats:

  • HH:MM (24-hour) or h:mm am/pm
  • Relative: now + 45 minutes, now + 2 days
  • Named: noon, midnight, teatime (4 pm)

The “cron” Daemon and the “crontab”

cron runs jobs on a recurring schedule defined by fields in a crontab file.

Anatomy of a Crontab Entry

Managing Crontabs

Edit your user’s crontab:

crontab -e

List your scheduled jobs:

crontab -l

Edit a crontab for a specific user – Considering, for instance, that the username is “thor”:

crontab -e -u thor

Remove all your jobs:

crontab -r

List and remove jobs for a particular username, respectively:

crontab -l -u thor
crontab -r -u thor

System-wide schedules live in:

  • /etc/crontab
  • /etc/cron.d/ (drop-in files)
  • /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly

Special Strings to use on crontab

Instead of five fields, you can use shortcuts:

ShortcutEquivalent
@rebootRun once at system boot
@yearly0 0 1 1 *
@monthly0 0 1 * *
@weekly0 0 * * 0
@daily0 0 * * *
@hourly0 * * * *

Comparison: at vs. cron

Here is a basic comparison between at and cron:

Featureatcron
FrequencyOnceRepeating
Configuration fileatq queues; /var/spool/at job filescrontab -e; /etc/cron.*
Use caseAd hoc, immediate schedulingRegular, periodic maintenance and jobs
Removalatrm <jobID>crontab -r (user) or edit crontab

Scheduling Jobs with “at”

Firstly, check if the daemon “atd” is running:

systemctl status atd

If the “atd” daemon is not running, enable and start it:

systemctl enable --now atd

Let’s provide an example of using “at” to schedule a one-time job:

echo "hello world" > greetings.txt | at 07:36 am

As we can see, the command “echo” was scheduled to run at a specific time:

As a result, the file “greetings.txt” was created correctly:

To see the “at” job queue (jobs pending to be executed):

atq

In this case, for instance, the job ID “3” is pending execution:

To remove a pending job:

atrm <JOB_ID>

In this example, the job ID “4” was removed successfully:

Scheduling Jobs with “cron”

Before starting, check if the “crond” daemon is running:

systemctl status crond

If the daemon is not running, enable and start it first:

systemctl enable --now crond

Let’s create a crontab entry considering that the current user is “thor”:

crontab -e

# Add the following entry:
*/2 * * * * /home/thor/jobs/scripts/hello_world.sh >> /home/thor/jobs/logs/hello_world.log 2>&1

Where:
*/2 –> Runs every 2 minutes
/home/thor/jobs/scripts/hello_world.sh –> Script to be executed
/home/thor/jobs/logs/hello_world.log –> Log file, in case of errors or something that is not expected

To inspect the user’s crontab:

crontab -l

To remove the user’s crontab:

crontab -r

Common Cron Examples

1- Run a script every day at midnight:

0 0 * * * /home/user/backup.sh

2- Run a command every 15 minutes:

*/15 * * * * /usr/bin/php /var/www/html/cron.php

3- Run a job every Monday at 8 AM:

0 8 * * 1 /home/user/monday_report.sh

4- Run a job on the 1st day of every month at 5 AM:

0 5 1 * * /home/user/monthly_cleanup.sh

5- Run a job only in December at 10 AM:

0 10 * 12 * /home/user/holiday_script.sh

6- How do you schedule a cron job to run every Sunday at 3 AM?

0 3 * * 0 /path/to/your/script.sh

0 3: At 3:00 AM
* *: Every day and every month
0: Sunday (can also use 7)

7- What does */10 * * * * mean?

*/10 * * * * /path/to/your/script.sh

This runs the job every 10 minutes.

  • */10: Every 10 minutes
  • The remaining * * * * means every hour, every day, every month, and every day of the week.

8- How do you redirect the output of a cron job to a log file?

0 0 * * * /home/user/script.sh >> /home/user/script.log 2>&1
  • >>: Appends standard output to the log file
  • 2>&1: Redirects standard error to the same log file

This ensures both output and errors are logged.

9- How do you ensure a cron job runs only on weekdays?

0 9 * * 1-5 /path/to/your/script.sh
  • 1-5: Monday to Friday
  • 0 9: At 9:00 AM

This skips weekends entirely.

10- How do you check if your cron job ran?

grep CRON /var/log/syslog       # Debian/Ubuntu
grep CRON /var/log/cron         # CentOS/RHEL

That’s it for now 🙂