Scheduling One-Time Jobs with Linux at Command

The at command in Linux is a dedicated utility used to queue tasks for a single, non-recurring execution at a specified date and time. Unlike cron, which automates repetitive tasks on an ongoing schedule, at allows system administrators and users to define jobs that run once and are automatically removed from the queue upon completion. This article details the underlying architecture of the at command, its operational syntax, and the tools available to monitor and manage queued tasks.

The Mechanism: The atd Daemon

The execution of any job scheduled with at depends on the atd background daemon. The atd process continuously runs in the background, waking up periodically (usually every 60 seconds) to check the spool directory (typically /var/spool/cron/atjobs or /var/spool/at/) for jobs that have reached their execution timestamp.

If the atd service is stopped or disabled, jobs will remain in the queue and fail to execute until the service is restored. You can verify and enable the daemon using standard systemd commands:

sudo systemctl enable --now atd

Scheduling Jobs with at

The at command accepts human-readable time specifications and reads instructions from standard input.

Basic Time Syntax

The utility supports flexible time formats, including:

Submitting Commands

When you invoke at with a target time, it opens an interactive prompt (at>) where you can enter one or more commands. Press Ctrl+D on a new line to save the commands and submit the job:

$ at 02:00 tomorrow
warning: commands will be executed using /bin/sh
at> /usr/bin/tar -czf /backups/site.tar.gz /var/www/html
at> <EOT>
job 3 at Thu Nov 14 02:00:00 2024

Alternatively, you can pipe commands directly into at or specify a script file using the -f flag to bypass the interactive prompt:

# Using a pipe
echo "/path/to/script.sh" | at now + 30 minutes

# Using a script file
at 23:00 -f /path/to/backup.sh

Environment and Output Handling

When an at job is scheduled, the command captures the current user's environment, including the working directory, shell variables, and umask. The job runs under the executing user’s privileges.

Because the job runs detached from an active terminal, any standard output (stdout) or standard error (stderr) generated by the commands is emailed to the user via the system's local mail transfer agent (such as Postfix or Sendmail). To avoid unnecessary local mail, standard output and errors can be redirected to a log file:

at now + 1 hour <<< "/opt/cleanup.sh > /var/log/cleanup.log 2>&1"

Managing the Job Queue

Linux provides built-in utilities to inspect and delete tasks stored by at.

Viewing Queued Jobs (atq)

To view the current list of pending jobs, use the atq command (or at -l). This displays the job identification number, date, time, job class, and the user who owns it:

$ atq
3       Thu Nov 14 02:00:00 2024 a user
4       Wed Nov 13 18:45:00 2024 a user

To view the full environment and script associated with a specific job without executing it, run at -c <job_id>.

Canceling Jobs (atrm)

To remove a job before its scheduled execution time, use the atrm command followed by the job ID:

atrm 3

Regular users can only view and remove their own jobs, whereas the root user can view and manage all jobs in the queue.

Access Control

System administrators can restrict access to the at command using two configuration files:

If neither file exists, system configuration determines access, typically defaulting to granting permission solely to the root user.