Schedule One-Time Jobs with at in Linux
Learn how to schedule one-time Linux commands with at, use absolute and relative times, inspect jobs with atq, remove them with atrm, and run command files with logs.
The Linux at command schedules a command or group of commands to run once at a future time. The submitted commands are placed in a queue and later run by the system's at scheduling service.
Use at for a one-time task, such as creating a file later, running a delayed cleanup, or starting a maintenance command at a specific time. For tasks that repeat on a schedule, use a recurring scheduler such as cron instead.
This lesson assumes that you can use a shell, understand basic command arguments, work with files and directories, and use basic shell redirection. For related shell concepts, see Bourne Again Shell Bash, Show the Full Path Of Shell Commands, and File Structure In Linux.
How at One-Time Scheduling Works
A one-time job has three stages:
- You submit commands with a time specification, which identifies when they should run.
- The commands enter the queue, the collection of pending jobs waiting for execution.
- The system's at scheduling service runs the commands once their scheduled time arrives.
The command runs according to the system clock and timezone. It does not automatically repeat after it finishes.
Start an Interactive at Job
The basic syntax is:
at TIME_SPECIFICATION
After you run this command, the shell displays an at prompt. This is an interactive input mode where you enter one or more shell commands for the future job.
$ at now + 2 min
at> echo "scheduled task ran" >> /home/bob/tmp/log.txt
at>
Press Ctrl+D on an empty line to submit the commands. Ctrl+D sends an end-of-file signal to the interactive input, so the at prompt closes and the job is added to the queue.
job 3 at Tue Aug 18 14:32:00 2026
The exact confirmation format varies by system, but it commonly includes the assigned job number and scheduled time.
Enter More Than One Command
You can enter multiple commands before pressing Ctrl+D. They are submitted as one job and run in the order entered.
$ at now + 10 min
at> cd /home/bob/tmp
at> echo "starting" >> task.log
at> touch task-complete
at> echo "finished" >> task.log
at>
Press Ctrl+D after the final command. The commands are interpreted by a shell when the job runs, so normal shell syntax can be used. For reliable unattended jobs, prefer explicit paths and avoid assuming that an interactive terminal is available.
Use Absolute Time
An absolute time names a particular clock time and calendar date. A common form is:
at 18:20 July 26 2015
This example means 18:20 on July 26, 2015. Because that date is now in the past, use a future date appropriate to your system when testing it:
$ at 18:20 July 26 2027
at> touch /home/bob/tmp/task-complete
at>
The job runs at the specified date and time, subject to the system clock and timezone. If the expression is ambiguous, or if the system clock is incorrect, the job can run at an unexpected time. Verify the system's current date, time, and timezone before scheduling important work. Network time synchronization, described in Network Time Protocol NTP, can help keep system clocks accurate.
Use Relative Time
A relative time schedules a job based on the current time. The general form is:
at now + NUMBER UNIT
Useful units include minutes, hours, days, and weeks. For example:
at now + 2 min
at now + 1 hour
at now + 3 days
at now + 2 weeks
Practical Example: Run a Command in Two Minutes
The following example opens the at prompt, enters one command, and submits the job with Ctrl+D:
$ at now + 2 min
at> echo "scheduled task ran" >> /home/bob/tmp/log.txt
at> [Ctrl+D]
job 3 at Tue Aug 18 14:32:00 2026
The first line starts at. The second line is the command saved for later execution. The Ctrl+D action submits the job. After approximately two minutes, the message is appended to the log file.
Create the destination directory first if it does not exist:
mkdir -p /home/bob/tmp
List Pending Jobs with atq
The atq command displays pending jobs in the queue:
$ atq
3 Tue Aug 18 14:32:00 2026 a bob
Output formatting can differ between implementations. It commonly contains:
- The job number, such as
3. - The scheduled date and time.
- A queue identifier, often a letter such as
a. - User context, where the implementation displays it.
The first field is normally the job number. Save this value if you may need to remove the job.
Remove a Queued Job with atrm
The atrm command removes a pending job by its job number:
atrm JOB_NUMBER
For example, find a job and remove job 3:
$ atq
3 Tue Aug 18 14:32:00 2026 a bob
$ atrm 3
$ atq
Run atq again to confirm that the job is no longer listed. Removal affects jobs that have not yet run. If a job has already executed, it cannot be removed from the pending queue. You generally must use the account that owns the job.
Schedule Commands from a File
The -f option tells at to read commands from a file instead of opening an interactive prompt. This is useful for multi-step tasks, repeatable job definitions, and scripts that are easier to review before submission.
$ cat > /home/bob/tmp/at_example.txt <<'EOF'
rm -f /home/bob/tmp/old-file-1 /home/bob/tmp/old-file-2
echo "cleanup completed at $(date)" >> /home/bob/tmp/log.txt
EOF
$ at -f /home/bob/tmp/at_example.txt 18:37 July 26 2027
The file contains two commands: one removes two files, and the other records a completion message. Replace the example date with an appropriate future date before running it.
The file supplied with -f is read when the job is submitted. After submission, the source file does not need to remain present for the queued job to run, because at has already accepted the job contents. Keep the file if you want a record of the job definition, but its later availability is not required for execution.
Capture Output and Errors
An unattended job may not have a visible terminal. Redirect both standard output, called stdout, and standard error, called stderr, to a known log file:
/usr/bin/some-command >> /home/bob/tmp/task.log 2>&1
The >> operator appends normal output to the log. The 2>&1 part sends error output to the same destination. A complete scheduled command might be:
$ at now + 5 min
at> echo "started $(date)" >> /home/bob/tmp/task.log 2>&1
at> /usr/bin/some-command >> /home/bob/tmp/task.log 2>&1
at> echo "finished $(date)" >> /home/bob/tmp/task.log 2>&1
at> [Ctrl+D]
Use a status message containing date so that you can tell whether the job started and finished. Also check that the user running the job can write to the log location.
Understand the Execution Environment
Scheduled commands commonly run with a limited, non-interactive environment. Their PATH, working directory, shell startup behavior, and available environment variables may differ from those in your terminal.
- Use absolute paths for executables, such as
/usr/bin/date, when reliability matters. - Use absolute paths for input, output, and temporary files.
- Change to the intended directory explicitly if a command depends on its working directory.
- Set required environment variables in the submitted commands instead of assuming they exist.
- Do not depend on an interactive prompt, terminal input, aliases, or shell functions unless you define the required behavior explicitly.
For example:
$ at now + 1 hour
at> cd /home/bob/application
at> /usr/bin/python3 /home/bob/application/backup.py >> /home/bob/tmp/backup.log 2>&1
at> [Ctrl+D]
Troubleshooting at Jobs
at Is Unavailable or Jobs Never Run
If the command is not found, the distribution's at package may not be installed. If jobs are accepted but never execute, the system's at scheduling daemon or service may not be running.
- Install the at package using the package manager for your Linux distribution.
- Check the system's documentation for the appropriate at service or daemon.
- Enable and start that service according to the system's service-management tools.
- Submit a short test job and inspect it with
atq.
A Command or File Cannot Be Found
A job may use a different PATH or working directory than your interactive shell. Relative paths can therefore refer to unexpected locations.
- Use absolute executable paths.
- Use absolute file paths.
- Set environment variables explicitly.
- Use
cdinside the job before operating on relative names.
There Is No Visible Result
If output was not redirected, there may be no convenient record of what happened. The command may also have failed without creating an observable result.
- Redirect stdout and stderr to a known log file.
- Add date-stamped start, success, and failure messages.
- Check the job with
atqbefore its execution time. - Verify that the scheduled user has permission to run the command and write the log.
The Job Runs at an Unexpected Time
An ambiguous time expression or an incorrect system clock or timezone can produce an unexpected schedule.
- Use an explicit clock time and calendar date.
- Verify the current system time and timezone.
- Use a relative expression such as
now + 2 minfor short tests.
atrm Does Not Remove the Intended Job
The job number may be incorrect, the job may already have executed, or the job may belong to another user.
- Run
atqand copy the current job identifier. - Remove the job before its scheduled execution time.
- Use the account that owns the queued job.
Quick Reference
# Open an interactive job two minutes from now
at now + 2 min
# Open an interactive job for an explicit date and time
at 18:20 July 26 2027
# List pending jobs
atq
# Remove a pending job
atrm JOB_NUMBER
# Submit commands from a file
at -f /home/bob/tmp/at_example.txt 18:37 July 26 2027
# Append output and errors to one log
/usr/bin/some-command >> /home/bob/tmp/log.txt 2>&1
Key Exam Notes
- at schedules a command or set of commands for one future execution.
- The time specification can be absolute, such as
18:20 July 26 2027, or relative, such asnow + 2 min. - Interactive commands are entered at the at prompt and submitted with Ctrl+D.
- atq lists pending jobs.
- atrm removes a pending job by its job number.
- -f reads job commands from a file at submission time.
- Use absolute paths and redirect stdout and stderr when reliability and later diagnosis matter.