Task Scheduling in Linux with cron and at command

Task scheduling allows you to run specific tasks at a particular time. Linux offers two native tools for task scheduling: at and cron. This tutorial explains how to use the at tool for task scheduling.

Installing the at tool

Most Linux distributions provide the at utility with the default installation. However, if it is not available, use the following command to install it.

On RedHat-based distributions (RedHat, CentOS, Fedora, etc.)

#dnf install at [Use if login with the root user]
or
$sudo dnf install at [Use if login with a non-root user]

On Debian-based distributions (Debian, Ubuntu, Kubuntu, etc.)

$sudo apt update
$sudo apt install at

It installs the at package. The at package includes the atd daemon. The atd daemon provides the main at command and a few additional commands to make task scheduling easier. Use the following command to view all commands this daemon offers.

#dnf repoquery -l at | grep bin

installing the atd daemon

atIt is the main command of the package. It schedules jobs to run at the given time.
atqIt is equivalent to the at -l command. It lists the jobs queue.
atrmIt is equivalent to the at -r command. It accepts a job number as an argument. It deletes the specified job from the queue.
batchIt is equivalent to the at -b command. Instead of the time, it runs the scheduled job when the system load drops below 0.8.
atdIt is the daemon that provides all commands, features, and functions of the at package.
atrunIt is a script that runs the scheduled jobs by the at command. It periodically checks the job queue and executes the scheduled jobs based on their specified time frame.

Starting/enabling the atd daemon

The atd daemon must be running to use the at and related commands. Start it if it is stopped or enable it if it is disabled. The systemctl command controls all daemons. It provides various options to manage daemons. The following table lists the essential options.

systemctl status [daemon_name] Display the current status
systemctl start [daemon_name] Start the daemon in the running session
systemctl stop [daemon_name] Stop the daemon in the running session
systemctl restart [daemon_name] Restart the daemon in the running session
systemctl enable [daemon_name] Enable and start the daemon at boot time
systemctl disable [daemon_name] Disable and stop the daemon at boot time

The following command displays the current status of the atd daemon.

#systemctl status atd

systemctl status atd

The following command stops the atd daemon.

#systemctl stop atd

systemctl stop atd

The following command starts the atd daemon.

#systemctl start atd

systemctl start atd

The date command

The at command schedules tasks or scripts to run at the specified time. It uses the system time to calculate the provided time. The date command without any arguments or options prints the current date and time.

#date

date

Task scheduling with the at command

The at command needs a job and a time as arguments. A job can be any executable resource, such as a command or a script. There are three ways to specify the job to the at command.

  1. Using piping
  2. Using interactive mode
  3. Using a batch or script file

Using piping

Piping is the standard shell feature. It redirects the output of a command as the input of another command. It uses a bar (|) sign. It takes the output from the left-side command and supplies it as the input to the right-side command.

piping

You can use this feature to specify the command or script you want the at command to schedule. However, it is not as simple as it sounds. If you directly specify the command, the command executes, and the at command receives the output, not the command itself. Let us take an example. Suppose you want the at command to schedule the ls command to run after one minute. If you use the following command, it will be incorrect.

#ls | at now + 1 minute

If you use the above command, the shell will execute the ls command and send the output to the at command as the input.

incorrect piping

The at command needs the command you want to run, not the output of the command you want to run.

You can use the echo command to solve this issue. The echo command prints the value of the specified variable. If you provide a quote-enclosed text string to it as an argument, it displays that as it is. Using this feature, if you specify a command after enclosing it with quotes, it prints that as it is on the terminal. For example, the following command generates the ls command as the output.

#echo 'ls'
ls
#

echo command

If you redirect this output to the at command, the at command receives the command, not the output.

#echo 'ls'  | at  now + 1 minute

correct at command

If the command needs arguments and options, enclose them with the command. For example, if you want to use the -l option with the ls command, use the following command.

#echo 'ls -l'  | at  now + 1 minute

correct way to specify command

There is one more thing that you need to adjust. If the command generates an output on the terminal, specify the terminal path or the location where you want to display or save the output. To view the output on the current terminal, use the output of the tty command. The tty command displays the path of the current terminal. For example, the ls command lists the content of the specified directory. It generates the output on the terminal. If you do not provide the output location, the command will execute, but nothing will display on the screen. For example, the following command will show nothing on the terminal after one minute.

#echo 'ls -l'  | at  now + 1 minute

at command example

To view the output on the terminal, redirect the output to the terminal. To view the terminal path, use the tty command.

#tty
/dev/pts/0

Use the terminal path with the command to receive the output on the terminal.

#echo 'ls -l > /dev/pts/0'  | at  now + 1 minute

at command now

If the command does not generate a terminal output, there is no need to specify the terminal path. For example, the mkdir command creates a directory but does not display any message on the terminal unless it encounters an error. In that case, you can specify only the command and its arguments.

#echo 'mkdir /testdir' | at  now + 1 minute

The above command creates a directory (/testdir) after one minute. However, it does not generate any notification on the screen. You need to manually check the destination path to verify the execution of the command.

#ls /testdir

If the destination contains the directory, it verifies the command executed at the scheduled time.

at command example 2

If the command accepts arguments in quotes, use double quotes. For example, the echo command accepts the text string in quotes. If you want the at command to schedule a job for it, use double quotes for the command that will be passed as the text string to the at command. The following at command schedules the echo command to display a hello message on the terminal after one minute.

#echo 'echo "hello" > [terminal path]' | at now + 1 minute
at command example 3

If you want to save the output in a file, specify the file path. For example, the following command saves the output in the file /testdir/testfile.

#echo 'echo "hello" > /testdir/testfile' | at now + 1 minute
at command example 4
Right side of the pipe

The at command works on the right side of the pipe. It requires a specific time as an argument to schedule the job. It supports all standard time formats. You can specify the time in any format of your choice.

24-Hour format
  • HH:MM
12-Hour format
  • HH:MM AM
  • HH:MM PM

The following command specifies the time in a 24-hour format.

#echo 'echo "hello" > /dev/pts/0'  | at 17:52

The following command specifies the same time in a 12-hour format.

#echo 'echo "hello" > /dev/pts/0'  | at 05:52 PM

at command example 5

Commonly used time formats

It also supports widely used time formats.

now Current date and time
midnight 00:00 AM
noon 12:00 PM
teatime 4 PM
today Current day
tomorrow Day after the current day

The following are examples of the above time formats.

#echo 'echo "hello" > /dev/pts/0'  | at now
#echo 'echo "hello" > /dev/pts/0'  | at midnight
#echo 'echo "hello" > /dev/pts/0'  | at noon
#echo 'echo "hello" > /dev/pts/0'  | at teatime
#echo 'echo "hello" > /dev/pts/0'  | at tomorrow

at command example

Using relative time

To specify a relative time, use the plus (+) sign. You can use relative time with all standard units. The following are examples of the relative time formats.

Current time + five minutes

#echo 'echo "hello" > /dev/pts/0'  | at now + 5 minutes

Current time + 2 hours

#echo 'echo "hello" > /dev/pts/0'  | at now + 2 hours

at command example 10

Using interactive mode

In interactive mode, you can schedule multiple commands to run at a specific time. Use the following syntax to start the interactive prompt.

#at [time]
> command or script to schedule
> command or script to schedule
Ctrl+ D

The Ctrl+D saves the job queue.

Since the atd daemon provides this prompt, you do not need to use the echo command to schedule the job. However, you need to specify the output location.

at command interactive prompt

Using a batch or script file

The -f option allows you to specify a batch or script file. It uses the following syntax.

#at [time] -f [script file location]

The following command schedules the my.sh script to run at 04:37 PM.

#at 04:37PM -f /testdir/my.sh

The script file you schedule to run must be executable. The chmod command with +x option makes a script file executable.

at command using file

Scheduling a task based on the system load average

Instead of time, if you want to schedule a task based on the system load, use the batch command or at command with the -b option. It schedules a task to run when the system load average drops below 0.8. It allows you to run bulky scripts in the idle time. The following command runs the /testdir/my.sh script when the system load average drops below 0.8.

#echo '/testdir/my.sh' | batch

at command batch option

Viewing jobs queue

Use the atq command or at command with the -l option to list all scheduled jobs in the queue.

#atq
#at -l

listing jobs

Deleting a job from the queue

To delete a scheduled job, use the atrm command or the at command with the -r option. It needs a job number. Use the atq command to view the job number of all scheduled jobs.

#atrm [job number]

removing job

Securing the atd daemon

By default, all users are allowed to use the atd daemon. If you want to allow or deny specific user accounts, use the following two files.

  1. /etc/at.allow
  2. /etc/at.deny

The /etc/at.allow file

This file allows users to use the atd daemon. If you use this file, only the user accounts listed in it can use the atd daemon. All remaining accounts can not use the atd daemon. Use this file to allow only specific user accounts while blocking all remaining accounts.

The /etc/at.deny file

This file blocks users from using the atd daemon. If you use this file, only the user accounts listed in it cannot use the atd daemon. All remaining accounts can use the atd daemon. Use this file to block only specific user accounts while allowing all remaining accounts.

Example

Create two accounts: user1 and user2.

adding user accounts

Create the /etc/at.allow file and add user1 to it.
Switch to user1 and schedule a task to verify that user1 is allowed.
Switch to user2 and schedule a task to verify that all remaining users are denied.

etc-at-allow file

Switch to root user and delete the /etc/at.allow file.
Create the /etc/at.deny file and add user1 to it.
Switch to user1 and schedule a task to verify that user1 is denied.
Switch to user2 and schedule a task to verify that all remaining users are allowed.

etc-at-deny-file

Conclusion

This tutorial explained how to use the at command for task scheduling. Task scheduling is essential for system administration. It allows you to execute commands and scripts at a specific time automatically. The at tool is for one go. The cron tool is for repetitive tasks.

ComputerNetworkingNotes Linux Tutorials Task Scheduling in Linux with cron and at command

We do not accept any kind of Guest Post. Except Guest post submission, for any other query (such as adverting opportunity, product advertisement, feedback, suggestion, error reporting and technical issue) or simply just say to hello mail us ComputerNetworkingNotes@gmail.com