Like cron, the at command allows us to run scheduled jobs in Linux. But while both are task schedulers, their use cases are dissimilar. The at command is especially useful when system resources like memory are crucial for running programs. We can think of it as a command for scheduling programs to run when system resources are at their freest. But with cron, usage extends beyond the availability of system resources.
In this tutorial, we’ll deep dive into the at command. We’ll go over its installation, usage, and more.
2. Installing at
Here’s how to install at on Debian or Ubuntu using apt:
$ sudo apt update $ sudo apt install at
When working on RHEL-based distributions like Fedora and CentOS, we install at by running this command:
$ sudo dnf install at
3. General Usage of the at Command
The at command allows us to schedule jobs using any of two commands: at and batch. While at runs commands at our specified time, batch runs commands when our system’s load average is below 0.8. So, depending on what we want, we can use either of them. But in this section, we’ll discuss the different ways of scheduling a job using the at command.
3.1. Using the at Command Prompt
The simplest way to schedule a job using at is to pass the job to the at command prompt.
We can echo “Hello World” at 18:00:
$ at 18:00
On running the command above, we get a command prompt:
$ at 18:00 warning: commands will be executed using /bin/sh at>
Then, let’s enter our command:
$ at 18:00 warning: commands will be executed using /bin/sh at> echo "Hello World"
Then we press the Enter key, and after that, we press Ctrl + D to save the job and exit.
After saving the job, we get a confirmation:
$ at 18:00 warning: commands will be executed using /bin/sh at> echo "Hello World" at> <EOT> job 10 at Sat Jan 28 18:00:00 2023
3.2. Using a Shell Script File
Besides the at command prompt, we can also run scheduled tasks by passing a shell script file to the at command using the -f option.
Let’s run a file at 00:00 (midnight):
$ at 00:00 -f /home/ubuntu/file.sh
3.3. Using Pipe and echo
We can also pass the command for the scheduled job to at using pipe and echo.
Here’s how we schedule a task to echo “Hello World” at midnight:
$ echo "echo 'Hello World'" | at 00:00
We can also show the system’s time settings using the same method:
$ echo "timedatectl" | at 00:00
3.4. Using a heredoc Block
A fourth way to schedule at jobs is to use a heredoc block:
$ at 00:00 <<END > echo "Hello World" > END
4. Time Specification for at Commands
We get a lot of flexibility when specifying the time at which the at command should run our job. We may choose to pass a specific time to at like we did above. But apart from that, we can also specify the date. Then, in place of specific time (HH:MM), we may use customary times and relative times.
If we don’t specify time correctly when running at, we’ll get an error message:
$ at 12 syntax error. Last token seen: 12 Garbled time
4.1. Using Specific Time
We can pass the specific time we want the at command to run our tasks in two ways:
- 24-hour clock format
- 12-hour clock format
Let’s schedule a midnight job for file.sh:
$ at 00:00 -f /home/ubuntu/file.sh
This command also does the same thing:
$ at 12am -f /home/ubuntu/file.sh
Running any of these two commands schedules the same job for 5 minutes past midnight in either of the two formats:
$ at 00:05 -f /home/ubuntu/file.sh
$ at 12:05am -f /home/ubuntu/file.sh
If our specified time has already passed for the day, the task will be scheduled for that same time the next day.
4.2. Using Customary Times
Besides using specific times, we can schedule at tasks using customary times:
- teatime (4pm)
To execute our script at midnight we can use this command:
$ at midnight -f /home/ubuntu/file.sh
Then let’s have script to run at 4pm:
$ at teatime -f /home/ubuntu/file.sh
4.3. Using Relative Times and Days of the Week
Apart from the customary times above, we can run at commands using relative times:
We can also use the days of the week (Monday – Sunday).
Using any of these two commands runs file.sh immediately:
$ at now -f /home/ubuntu/file.sh
$ at today -f /home/ubuntu/file.sh
Similarly, we can run file.sh in exactly 24 hours:
$ at tomorrow -f /home/ubuntu/file.sh
Then again, we can schedule the task to run at the current time on Friday:
$ at Friday -f /home/ubuntu/file.sh
Since the at command is meant for executing commands at a later time, we rarely use now and today alone. Instead, we typically use them alongside other measures of time. Besides those two, we also use tomorrow and the days of the week alongside other measures of time.
today, tomorrow, and the days of the week can be used with 12-hour-clock times and 24-hour-clock times.
Running this command will schedule file.sh for 3:05pm today:
$ at 3:05pm today -f /home/ubuntu/file.sh
Similarly, we can execute the same file tomorrow at 3:05pm:
$ at 15:05 tomorrow -f /home/ubuntu/file.sh
Also, we can make the job run at 3:05pm on the next Monday:
$ at 3:05pm Monday -f /home/ubuntu/file.sh
We can also use now, today, tomorrow, and the days of the week alongside time units such as minutes, hours, days, and weeks.
Either of these two executes file.sh three hours from the current time:
$ at now +3 hours -f /home/ubuntu/file.sh
$ at today +3 hours -f /home/ubuntu/file.sh
Using this runs the same file four days from tomorrow:
$ at tomorrow +4 days -f /home/ubuntu/file.sh
Then this runs the script at the current time two weeks from Friday:
$ at Friday +2 weeks -f /home/ubuntu/file.sh
If we don’t want the jobs to be executed at our current time on the scheduled day, we can add a specific time to the at command.
Let’s schedule file.sh for 2pm two weeks from Friday:
$ at 14:00 Friday +2 weeks -f /home/ubuntu/file.sh
This syntax also applies to today, tomorrow, and the days of the week.
4.4. Specifying Date
The at command also allows us to specify the date on which we want to execute a job. So, we can easily schedule jobs many months or years in the future.
This is how we can slate file.sh to run on Aug 16:
$ at Aug 16 -f file.sh
We can even specify the year:
$ at Aug 16 2024 -f file.sh
We may choose to write the month name in full (August) instead of writing it as “Aug”.
In place of using the month name and day, we can also use the MM/DD/YY, MMDDYY, DD.MM.YY, or YY-MM-DD formats. The YY can be written either fully (YYYY) or abbreviated (YY).
So, the file.sh job for Aug 16 could also be any of these:
$ at 08/16/23 -f file.sh
$ at 16.08.23 -f file.sh
$ at 23-08-16 -f file.sh
$ at 081623 -f file.sh
Every one of the commands above does the same thing: schedule at to execute file.sh at the current time on August 16, 2023.
If we want at to run file.sh at any other time (e.g., 4pm) on August 16, 2023, our command could be any of these:
$ at 4pm 08/16/2023 -f file.sh
$ at 4pm 08162023 -f file.sh
$ at 4pm 16.08.2023 -f file.sh
$ at 4pm 2023-08-16 -f file.sh
As opposed to 4pm, we can use 16:00 or teatime. Similarly, if we are scheduling the task for 12am, we can use 00:00 or midnight.
We can also schedule an at task for a particular day down to the hour, minute, and second we want it to run. For this, we’ll need the -t flag and the YYMMDDhhmm.ss format. The YY can be written either fully (YYYY) or abbreviated (YY). Also, YY and ss are optional.
Executing the command below makes at run file.sh on August 16 at 17:08:30:
$ at -t 2308161708.30 -f file.sh
5. Using the batch Command
As we mentioned earlier, batch (also at -b) executes jobs when the load average drops below 0.8 (we can check our system’s load average using uptime). Basically, batch runs jobs when there’s less pressure on the system’s resources.
We can use batch pretty much the same way we use at. However, since batch doesn’t accept parameters, we cannot pass a script file or time specifications to it. In other words, we can only run batch using at command prompt, heredoc block, and pipe & echo.
6. Listing Scheduled Jobs
This command shows us a list of all our scheduled jobs:
We can also use this alternative:
$ at -l
Listing our scheduled tasks shows us this output:
$ atq 84 Sat Jan 28 17:00:00 2023 a ubuntu
When we list scheduled jobs, the first number in the output is the job number. So, for the job above, the job number is 84.
After the job number, we have the time and date the job will be executed. Then we have “a”, the job’s queue. Finally, we have the user running the at command (ubuntu).
To list scheduled tasks in a specific queue, this works:
$ atq -q [queue]
Otherwise, we could run this command:
$ at -l -q [queue]
7. Deleting Scheduled Jobs
To delete a scheduled job, we can use any of these:
$ atrm [job number]
$ at -r [job number]
$ at -d [job number]
8. Adding Jobs to Specific Queues
Jobs scheduled using the at command are added to queue “a” by default. Those scheduled using batch are added to queue “b”. Then those that are currently running will appear under queue “=”.
If we want, we can specify a different queue for our jobs from a to z and from A to Z. The higher the letter of a queue, the higher the niceness of the tasks in that queue. In other words, if we add the same task to queue “a” and queue “z’, the one in “z” will run with a lower priority than the one in “a”.
Jobs in uppercase letter queues have even more niceness than the lowercase letters. They run as if they were passed with the batch command at the scheduled time of execution. To be precise, when the time comes for such jobs to be executed, they wait until load average falls below 0.8.
We can execute file.sh at 4pm and add it to queue “s”:
$ at 4pm -f file.sh -q s
9. Configuring at Mail
By default, when a job is executed, the at command sends the job’s standard output as a mail to the user. But if there’s no output, the user won’t get a mail.
To ensure we get a mail even if the task doesn’t produce a standard output, we can add the -m flag when scheduling the job. On the other hand, if we don’t want to receive a mail, we can suppress it using the -M flag.
We can schedule file.sh for 4pm while ensuring we receive a mail:
$ at 4pm -f file.sh -m
Here’s how we can schedule the same script for 4pm without receiving a mail:
$ at 4pm -f file.sh -M
10. Displaying the Content of a Scheduled Job
If we want to see the command or content of a scheduled task, we can run at with the -c option:
$ at -c [job number]
This displays the content of the job on the command line.
In this article, we thoroughly examined the at command. We went over pretty much every option that comes with the command and discussed what each one does.
The at command is most suitable for scheduling jobs we want to run once. However, if we wanted to schedule a job to run recurringly, we would opt for a task scheduler like cron.