Schedule commands for later using 'at'

in Linux, Console, scheduling

There have been a number of times when I've realized that I must restart some service at a production server. In such enviroments, restarting a critical service ( e.g. MySQL on a webserver ) in a production enviroment is simply a no-go during hours with traffic. And since the lowest possible traffic is during morning's early hours, you can either "schedule" your service restart to occur after going out with friends for a couple of beers, be awake {until|at} that time.... or simply let your server know that something needs to be done at that time.

Adding a scheduled job

The process is really simple - the at command allows you to schedule a number of commands ( Windows folk would call it a batch file, normal people would just call it a script ). You just need three simple steps:

  1. Enter the at command followed by the time ( and optionally date ) when you want something to be run. If for example you want to run a command at 4:00 on the 1st of February 2011, you should enter
    # at 04:00 01.02.2011
    At can handle a number of different ways to declare when you want your commands to be scheduled. Check at the end for a reference to possible syntax for time / date
  2. You will then be able to type the command you wish to be run at that time. Keep it at one command per line, for instance restart apache (httpd in most rpm-based systems, apache2 in debian)
    at> /etc/init.d/httpd restart
  3. When you finish entering the commands press CTRL+D

Manage existing jobs

In order to view all scheduled events, you can either use at -l or atq , which will display a list similar to the following

# atq
2	Tue Feb  1 04:00:00 2011 a hex
1	Fri Jan 28 00:00:00 2011 a hex
Do note that events are scheduled per user, and as such only the current user's events are shown in the list. The only exception is the root user, who sees all schedules events.

If you wish to remove an event from the list, you just need to know its id ( the first number in the above list ), and use the -r flag. For example, to remove the first job ( which is set to run on Jan 28 ), you would use

# at -r 1

A note about time / date formats

This is an extract from the man page for at, regarding the accepted time and date parameters:

 

At allows fairly complex time specifications, extending the POSIX.2 standard. It accepts times of the form HH:MM to run a job at a specific time of day. (If that time is already past, the next day is assumed.) You may also specify midnight, noon, or teatime (4pm) and you can have a time-of-day suffixed with AM or PM for running in the morning or the evening. You can also say what day the job will be run, by giving a date in the form month-name day with an optional year, or giving a date of the form MMDDYY or MM/DD/YY or DD.MM.YY. The specification of a date must follow the specification of the time of day. You can also give times like now + count time-units, where the time-units can be minutes, hours, days, or weeks and you can tell at to run the job today by suffixing the time with today and to run the job tomorrow by suffixing the time with tomorrow.

For example, to run a job at 4pm three days from now, you would do at 4pm + 3 days, to run a job at 10:00am on July 31, you would do at 10am Jul 31 and to run a job at 1am tomorrow, you would do at 1am tomorrow.

/usr/share/doc/at-3.1.8/timespec contains the exact definition of the time specification.