| |

LFCS 66 ๐Ÿง At Jobs โ€” One-Time Scheduling

โฑ๏ธ Estimated read: 13 min | |

The at command is the standard Linux utility for scheduling a command to run exactly once at a specified future time. Unlike cron, which repeats jobs on a schedule, at is designed for one-off tasks: a backup that needs to run in an hour, a reminder that must fire tomorrow morning, or a maintenance script that should execute after business hours. For the LFCS exam, this distinction mattersโ€”the “Manage or schedule jobs for executing commands” objective requires knowing when to reach for at and when cron is the correct tool.

This chapter covers the at command family: the daemon that must be running, the time specification syntax, the companion commands for listing and deleting jobs, and the access control files that determine which users may schedule jobs at all.

Key point: at jobs will not run if the atd daemon is not enabled and started. Installing the package is not sufficient; the service must be active.


Why at exists

The one-time scheduling problem. Cron is a repeating scheduler. Its smallest granularity is one minute, and its design assumes a job should run again and again. Some tasks do not fit that model. You need to run a command once, at a specific moment, and never again. Forcing that into cron requires scheduling a job and then remembering to remove itโ€”a fragile pattern. at exists precisely for this case: submit a job with a time, and the system runs it once and discards it.

The interactive submission problem. Many scheduled tasks are composed on the fly. An administrator decides at 2:15 PM that a service should be restarted at 3:00 PM. There is no crontab entry to edit; there is a single command to run once. at accepts commands from standard input or a file, making it natural to type a quick job at the shell and submit it without opening an editor.

The load-aware execution problem. The companion command batch reads commands the same way at does, but instead of running at a fixed time, it runs when system load permits . This is useful for non-urgent jobs that should not compete with interactive work. batch is part of the same package and shares the same submission model.

The accountability problem. Every at job is assigned a job number and queued in a specific letter queue. The atq command lists pending jobs with their numbers, dates, and owners. The atrm command deletes a job by number. This gives administrators a clear inventory of what is scheduled and the ability to cancel a job that is no longer needed. A cron job, by contrast, is identified only by its line in a file.


a. Installation and the atd Daemon

The at package provides the at, batch, atq, and atrm commands. On Debian and Ubuntu systems it is installed with apt; on RHEL-family systems, with dnf or yum.

# Debian/Ubuntu: install the at package
sudo apt update
sudo apt install at

# RHEL/Fedora: install the at package
sudo dnf install at

Installation alone is not enough. The atd daemon is responsible for monitoring the job queue and executing jobs when their time arrives. It must be enabled so it starts at boot, and started immediately so it runs in the current session .

# Enable atd to start on boot and start it immediately
sudo systemctl enable --now atd

# Verify that the daemon is active
sudo systemctl status atd

If atd is not running, at will accept and queue jobs, but they will never execute. This is the most common reason a scheduled job “disappears” silently. Checking systemctl status atd should be the first diagnostic step whenever an at job fails to run.


b. Time Specification Syntax

The at command accepts a remarkably flexible time syntax. The simplest form is a 24-hour time, HH:MM. If that time has already passed today, at assumes the job should run at that time tomorrow .

# Schedule a job for 3:30 PM today (or tomorrow if 15:30 has passed)
at 15:30

Named times are accepted: midnight, noon, and teatime (4 PM) . AM and PM suffixes work as expected.

# Schedule for 10:00 AM tomorrow
at 10am tomorrow

# Schedule for noon on a specific date
at noon July 31

Relative times use the form now + count unit. Units can be minutes, hours, days, or weeks . This is the most common form in practice because it does not require calculating an absolute timestamp.

# Run a job five minutes from now
at now + 5 minutes

# Run a job three days from now at 4 PM
at 4pm + 3 days

Dates can be specified in several formats: month-name day with optional year, MMDD[CC]YY, MM/DD/[CC]YY, DD.MM.[CC]YY, or [CC]YY-MM-DD . The date must follow the time.

Once the time is entered, at presents an interactive prompt (at>). Commands are typed line by line, and the job is submitted by pressing Ctrl+D on an empty line.

# Submit a job interactively
at now + 10 minutes
at> /usr/local/bin/cleanup.sh
at> echo "Cleanup finished" >> /var/log/cleanup.log
at> <Ctrl+D>

For non-interactive use, the -f option reads commands from a file. This is the preferred approach in scripts.

# Submit a job from a script file
at -f /opt/scripts/maintenance.sh now + 1 hour

The -m option sends mail to the user after the job completes, even if there is no output . By default, at mails the user only if the job produces output.

# Send mail on completion regardless of output
at -m now + 2 hours

c. Managing the Job Queue

Every submitted job receives a numeric job number. The atq command lists the current user’s pending jobs; when run by root, it lists everyone’s jobs . The output columns are job number, date, hour, queue, and username.

# List pending at jobs for the current user
atq

# As root, list all users' pending jobs
sudo atq

Jobs can be deleted by number with atrm. A user can only delete their own jobs; root can delete any job .

# Delete job number 5
atrm 5

# Alternative form using at -r
at -r 5

The queue designation is a single letter, a through z or A through Z. The default queue for at is a. Higher-letter queues run with increased niceness (lower priority). Uppercase queues are treated like batch: the job runs when system load permits after the specified time . For most LFCS tasks, the default queue is sufficient.

# Submit a job to queue b (slightly lower priority than default a)
at -q b now + 30 minutes

The -l option is an alias for atq, and -d is an alias for atrm. These exist for convenience but the dedicated commands are clearer.


Complete Example Session

# ============================================
# PART 1: VERIFY THE AT PACKAGE IS INSTALLED
# ============================================
# Check whether the at command exists
which at
# If no output, install the package
# Debian/Ubuntu:
sudo apt install at
# RHEL/Fedora:
sudo dnf install at


# ============================================
# PART 2: ENABLE AND START THE ATD DAEMON
# ============================================
# atd must be running for jobs to execute
sudo systemctl enable --now atd
# Confirm it is active (look for "active (running)")
sudo systemctl status atd


# ============================================
# PART 3: SUBMIT A JOB INTERACTIVELY
# ============================================
# Schedule a simple disk usage report
at now + 5 minutes
at> df -h > /tmp/disk-report.txt
at> echo "Report generated at $(date)" >> /tmp/disk-report.txt
at> <Ctrl+D>
# Output confirms the job number and scheduled time
# job 3 at Fri Oct 20 14:35:00 2026


# ============================================
# PART 4: SUBMIT A JOB FROM A FILE
# ============================================
# Create a script to run later
cat > /tmp/backup-job.sh <<'EOF'
#!/bin/bash
tar -czf /backups/etc-$(date +%F).tar.gz /etc
EOF
chmod +x /tmp/backup-job.sh

# Schedule it for 2 AM tomorrow
at -f /tmp/backup-job.sh 2am tomorrow


# ============================================
# PART 5: LIST PENDING JOBS
# ============================================
# Show the current user's queued jobs
atq
# Example output:
# 3       Fri Oct 20 14:35:00 2026 a root
# 4       Sat Oct 21 02:00:00 2026 a root


# ============================================
# PART 6: DELETE A JOB
# ============================================
# Remove job number 3 (no longer needed)
atrm 3
# Verify it is gone
atq


# ============================================
# PART 7: INSPECT A JOB'S CONTENTS
# ============================================
# View the commands queued for job 4
at -c 4
# This prints the script that will run, useful for verification


# ============================================
# PART 8: CHECK ACCESS CONTROL FILES
# ============================================
# Determine who can use at
ls -l /etc/at.allow /etc/at.deny 2>/dev/null
# If at.allow exists, only listed users may submit jobs
# If only at.deny exists, listed users are blocked
# If neither exists, only root may use at


# ============================================
# PART 9: RESTRICT ACCESS TO A USER
# ============================================
# As root, create at.deny and add a user
echo "baduser" | sudo tee /etc/at.deny
# baduser can no longer submit at jobs


# ============================================
# PART 10: USE BATCH FOR LOAD-AWARE JOBS
# ============================================
# Submit a job that runs when load is low, not at a fixed time
batch
at> /usr/local/bin/heavy-index.sh
at> <Ctrl+D>
# batch uses queue b and waits for load to drop below the threshold

The ten parts trace the full lifecycle: installation, daemon activation, interactive and file-based submission, queue inspection, deletion, access control, and the batch alternative. The critical dependency is atd; without it, every step after installation produces a queued job that never runs.


Quick Reference

At Command Options

OptionPurpose
-f fileRead commands from file instead of stdin
-mMail user on completion even without output
-q queueSubmit to a specific letter queue (default a)
-lAlias for atq
-dAlias for atrm
-c jobPrint the commands of a queued job

Time Specification Forms

FormExampleMeaning
Absolute time15:303:30 PM today or tomorrow
Named timemidnight, noon, teatimeFixed times of day
AM/PM10am10:00 AM
Relativenow + 5 minutesFive minutes from now
Relative with time4pm + 3 days4 PM three days from now
Date10am Jul 3110 AM on July 31
Tomorrow1am tomorrow1 AM next day

Companion Commands

CommandPurpose
atqList pending jobs (own jobs; all jobs as root)
atrm <job>Delete job by number
batchRun when system load permits
at -c <job>Display the commands of a job

Access Control Files

File ExistsBehavior
/etc/at.allow existsOnly listed users may use at
No at.allow, at.deny existsListed users are blocked
Neither file existsOnly root may use at

Best Practices

โœ… Do This:

# Enable atd and verify it is running
sudo systemctl enable --now atd                                         # โœ…
# Use -f for scripted job submission
at -f /opt/scripts/backup.sh 2am tomorrow                               # โœ…
# List jobs before deleting to confirm the job number
atq && atrm 5                                                           # โœ…
# Use at -c to verify a job's contents before it runs
at -c 4                                                                 # โœ…
# Use batch for non-urgent heavy jobs
batch < /opt/scripts/reindex.sh                                         # โœ…
# Restrict at usage with at.allow when security matters
echo "admin" | sudo tee /etc/at.allow                                   # โœ…

โŒ Don’t Do This:

# Install at but forget to start atd
sudo apt install at                                                    # โŒ
# Submit a job without checking the scheduled time
at now + 5 minutes                                                     # โŒ (verify with atq)
# Delete a job without listing first
atrm 5                                                                 # โŒ
# Assume a job ran; check mail or output
# No verification of execution                                          # โŒ
# Use at for repeating jobs
at 2am                                                                 # โŒ (use cron)
# Leave at.deny empty when restriction was intended
sudo touch /etc/at.deny                                                # โŒ (empty deny allows all)

Common Pitfalls

PitfallWhy It HappensFix
Job never executesatd daemon not runningsudo systemctl enable --now atd
Job output is lostNo redirection in the commandRedirect stdout/stderr to a file
Cannot submit job as a userAccess restricted by at.allow/at.denyCheck files; ask admin to add user
Time is misinterpretedPast time assumes next dayUse now + or verify with atq
Job runs but environment differsat retains limited environmentSet variables explicitly in the job
Deleting the wrong jobNo listing before atrmAlways atq first
at not foundPackage not installedsudo apt install at or sudo dnf install at

Real-World Examples

1. Schedule a One-Time Backup

at -f /opt/scripts/backup.sh 2am tomorrow

2. Run a Cleanup in Ten Minutes

at now + 10 minutes
at> /usr/local/bin/cleanup.sh
at> <Ctrl+D>

3. List All Pending Jobs as Root

sudo atq

4. Delete a Job by Number

atrm 7

5. Inspect a Job’s Commands

at -c 7

6. Mail Notification on Completion

at -m now + 1 hour

7. Submit to a Lower-Priority Queue

at -q b -f /opt/scripts/nightly.sh 1am

8. Restrict a User from at

echo "contractor" | sudo tee -a /etc/at.deny

9. Run When Load Is Low

batch < /opt/scripts/index-rebuild.sh

10. Schedule with a Specific Date

at 9am Dec 31

Visual

The At Job Lifecycle

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  USER SUBMITS JOB                                            โ”‚
โ”‚                                                              โ”‚
โ”‚  at now + 5 minutes                                          โ”‚
โ”‚  at> command                                                 โ”‚
โ”‚  at> <Ctrl+D>                                                โ”‚
โ”‚           โ”‚                                                  โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ Job queued      โ”‚  Job number assigned                   โ”‚
โ”‚  โ”‚ in /var/spool/  โ”‚  Queue letter (default a)              โ”‚
โ”‚  โ”‚ cron/at/        โ”‚                                        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚                                                  โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ atd daemon      โ”‚  Monitors the queue                    โ”‚
โ”‚  โ”‚ running?        โ”‚                                        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚ YES                                              โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ Time reached    โ”‚  atd executes the job                  โ”‚
โ”‚  โ”‚                 โ”‚  using /bin/sh                         โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚                                                  โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ Output mailed   โ”‚  If -m or if output exists             โ”‚
โ”‚  โ”‚ Job discarded   โ”‚  One-time: never runs again            โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                                                              โ”‚
โ”‚  If atd is NOT running, the job stays in the queue forever. โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Access Control Decision Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  USER ATTEMPTS TO RUN at                                    โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ Is user root?   โ”‚โ”€โ”€โ”€โ”€โ–บ YES: Allowed, always              โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚ NO                                               โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ /etc/at.allow   โ”‚โ”€โ”€โ”€โ”€โ–บ EXISTS: Only listed users allowed โ”‚
โ”‚  โ”‚ exists?         โ”‚      (if not listed, denied)          โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚ NO                                               โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ /etc/at.deny    โ”‚โ”€โ”€โ”€โ”€โ–บ EXISTS: Listed users denied       โ”‚
โ”‚  โ”‚ exists?         โ”‚      Others allowed                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚           โ”‚ NO                                               โ”‚
โ”‚           โ–ผ                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚  โ”‚ Only root       โ”‚  Default state when neither file       โ”‚
โ”‚  โ”‚ allowed         โ”‚  exists                                โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                                                              โ”‚
โ”‚  Empty at.deny = everyone allowed (default).                 โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

At Versus Cron

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  AT (one-time)              CRON (repeating)                 โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  โ”‚ Runs once       โ”‚        โ”‚ Runs on scheduleโ”‚             โ”‚
โ”‚  โ”‚ then discarded โ”‚        โ”‚ indefinitely    โ”‚             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  โ”‚ Submitted via   โ”‚        โ”‚ Edited in       โ”‚             โ”‚
โ”‚  โ”‚ command line    โ”‚        โ”‚ crontab file    โ”‚             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  โ”‚ Time: relative  โ”‚        โ”‚ Time: five-fieldโ”‚             โ”‚
โ”‚  โ”‚ or absolute     โ”‚        โ”‚ schedule syntax โ”‚             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”‚
โ”‚  โ”‚ Identify by     โ”‚        โ”‚ Identify by     โ”‚             โ”‚
โ”‚  โ”‚ job number      โ”‚        โ”‚ crontab line    โ”‚             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ”‚
โ”‚                                                              โ”‚
โ”‚  Use at for: backups in 1 hour, reminders, maintenance.     โ”‚
โ”‚  Use cron for: daily logs, hourly syncs, weekly reports.    โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Time Specification Parsing

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  INPUT                          INTERPRETATION               โ”‚
โ”‚                                                              โ”‚
โ”‚  15:30                          Today 3:30 PM                โ”‚
โ”‚                                 (or tomorrow if past)        โ”‚
โ”‚                                                              โ”‚
โ”‚  now + 5 minutes                Five minutes from now        โ”‚
โ”‚                                                              โ”‚
โ”‚  4pm + 3 days                   4 PM three days from now     โ”‚
โ”‚                                                              โ”‚
โ”‚  10am Jul 31                    10 AM on July 31             โ”‚
โ”‚                                                              โ”‚
โ”‚  1am tomorrow                   1 AM next day                โ”‚
โ”‚                                                              โ”‚
โ”‚  midnight                       Start of next day            โ”‚
โ”‚                                                              โ”‚
โ”‚  noon                           Next 12:00 PM                โ”‚
โ”‚                                                              โ”‚
โ”‚  teatime                        Next 4:00 PM                 โ”‚
โ”‚                                                              โ”‚
โ”‚  Dates must follow times.                                    โ”‚
โ”‚  Relative forms use "now +" for clarity.                     โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Packageat (provides at, batch, atq, atrm)
Daemonatd, enabled via systemctl enable --now atd
One-time schedulingat <time> then commands, Ctrl+D
File submissionat -f script.sh <time>
List jobsatq or at -l
Delete jobatrm <job> or at -r <job>
View jobat -c <job>
Mail on completionat -m
Access control/etc/at.allow, /etc/at.deny
Load-aware alternativebatch

Key takeaways:

  • atd must be running. Installing the package queues jobs but does not execute them. sudo systemctl enable --now atd is mandatory. Verify with systemctl status atd.
  • Time syntax is flexible but past times roll forward. at 2pm submitted after 2 PM schedules for tomorrow. Use now + 5 minutes when you need a guaranteed future time.
  • Jobs are identified by number. atq lists them; atrm deletes them. Always list before deleting to confirm the number.
  • Access is controlled by at.allow and at.deny. If at.allow exists, only listed users may use at. If only at.deny exists, listed users are blocked. If neither exists, only root may use at.
  • batch is the load-aware sibling. It queues jobs the same way but runs them when system load drops, making it suitable for non-urgent heavy work.
  • at is for one-time jobs; cron is for repeating jobs. Choosing the wrong tool creates maintenance burden or missed executions. The LFCS objective expects this distinction.

Remember: The at command answers a specific question: “Run this once, at this time.” It is not a replacement for cron, and cron is not a replacement for at. The daemon dependency is the detail that separates a working setup from a silent failureโ€”a queued job with no atd process is invisible until the deadline passes and nothing happens. Enable the daemon first, verify with atq, and use at -c to inspect what will actually run. For the LFCS exam, the command family, the daemon name, the time syntax, and the access control file precedence are the core facts to retain.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!