At Your Service—Job Scheduling for Linux

A simple command-line utility for planning and managing deferred program executions.

Drawing from the communications world, services fall in one of two broad categories, immediate or deferred. Immediate communication services include teleconferencing, on-line chat, etc.; while deferred services include e-mail and fax. This column presents an overview of the Linux at utility that allows for the deferred (or scheduled) execution of a program.

Of course, most programs need to be launched in an immediate, do-it-now mode. Still, it's often desirable and perhaps required to schedule the execution of a program (or job, in ancient Geek) at a particular time for a variety of practical reasons. Consider any of the following scenarios:

  1. A development group has developed a script that rebuilds their source tree and updates the application's staging area. The script is completely mechanized, but it is very time- and CPU-intensive. As a practical matter, the group decides this job should be scheduled to run in the late evening when it would be competing with fewer users and processes.

  2. A high-quality color printer/plotter is in high demand during regular business hours. Multiple times a week, a project manager uses the printer to reprint a quickly evolving project plan of 200+ pages. To avoid monopolizing the printer during its peak usage period, the project manager decides the print job should be run in the early morning—before most users are active.

  3. A project leader wants to distribute meeting reminder/agenda notes via e-mail to participating staff members four hours before a meeting scheduled for next Friday at 4:00 P.M.

  4. A system administrator (SA) has been receiving reports of extremely poor system performance at the start of the business day. The cause of the degrading performance is not obvious. Rather than comb through numerous system logs, the SA decides to schedule the execution of a program that captures system load information. The job is to be executed the next day, every five minutes during the 9:00 A.M. hour.

  5. An external data source used to update a local data warehouse becomes available at 6:00 P.M. every Friday. If the lengthy update procedure does not complete successfully, it's to be retried an hour later. Otherwise, it is rescheduled for the next Friday.

The scheduling requirements outlined in each of the above scenarios can be addressed by the at utility. Furthermore, these scenarios represent a broad range of the most common applications for at. The at utility is ideal for performing CPU-intensive tasks when little user-processing demand is present on the system, utilizing scarce resources at a time when they're generally more available, distributing reminders at a specific time, executing jobs that need to run at a time when the user has no intention of being actively connected to the system and executing jobs that are dependent on resources becoming available at a specific time.

at's Features

at is actually a collection of related programs that allow Linux users to schedule and manage the execution of deferred jobs. If you're thinking at is only suitable for noninteractive tasks, you are correct. Programs scheduled through at are expected to be capable of running as background processes, since at does not associate user-display devices with executing jobs. Users generally find the at command-line interface to be quite intuitive. Yet, it is expressive enough to meet any conceivable scheduling requirement. Before presenting examples of the command-line interface, let's summarize the basic services provided by at. It allows for scheduling the execution of a job at a specific time/date, displaying information about jobs currently scheduled, canceling a job currently scheduled and administrating the list of users that have permission to use at programs.

Using at

The examples presented here assume you have a basic familiarity with shell command execution and Bourne shell syntax. Each of the examples were tested on a Red Hat Linux 7 (2.3 kernel) platform. However, I would expect the examples to work as presented on all common distributions.

Obviously, the most fundamental capability offered by at is that of scheduling the execution of a program at some later time. Generally installed at /usr/bin/at, the basic command-line syntax for the at program is as follows:

at [options] TIME [DATE] < bourne-shell-file

This syntax implies the following alternate ways of invoking at would work as well:

cat bourne-shell-file | at [options] TIME [DATE]
at [options] TIME [DATE]
## Anything normally accepted by the bourne shell
## interpreter will be accepted. Terminate with
## Ctrl-D (^d)
statement 1
statement 2
statement 3
statement 4
The first significant detail here is the proper notation for the time and date. The date is always optional. When it's omitted from the command line, the date is assumed to be the next day the specified time will occur, that is, either today or tomorrow. For example, if the time is specified as 1:30 P.M. and it's already 4:30 P.M., the job will be scheduled for the next day at 1:30 P.M. at accepts a time/date notation that extends the POSIX.2 standards. That notation may be documented on your installation under the /usr/doc directory in a file called timespec.

Let's learn through some examples. The time/date specification examples in Table 1 will give you a good idea of what the at program will accept.

Table 1. Possible Time/Date Entries

As shown, the at program accepts a fairly rich and intuitive notation. It attempts to interpret the time/date specified by parsing its command-line arguments from left to right. If its time/date specification is violated, a “Garbled time” error diagnostic is displayed< and the program terminates. It usually provides a terse hint as to why it became troubled. For example, review the following invocation attempt below:

$ at 6am Mar 32
Error in day of month. Last token seen: 32
Garbled time

The following invocation succeeds at scheduling a job. Consider the third usage scenario outlined above for this submission:

$ at 1pm friday
warning: commands will be executed using /bin/sh
    STAFF="moe larry curly"
    cd mail
    mail -s"Meeting Reminder" $STAFF < friday_agenda.txt
job 6 at Fri Apr  13 13:00:00 2001
If you're following closely, some questions should begin to formulate. Do the standard output and standard error streams of a scheduled job get captured somewhere? All standard output and standard error diagnostics are captured by the at service (/usr/sbin/atd program) and e-mailed to the submitting user when the scheduled job finishes. The e-mail will appear with a subject heading such as the following:

Subject: Output from your job 17

Are we limited to scheduling Bourne shell scripts? As the feedback from the example above indicates, at uses the system Bourne shell program (/bin/sh) to interpret the user-provided program statements. Therefore, anything you would type at a Bourne shell prompt would be valid, including a Bourne shell script or the launch of any executable found in your environment, even a different language interpreter. Review the following example for scheduling the execution of a Perl script:

$ at 6pm tomorrow
warning: commands will be executed using /bin/sh
    perl /home/moe/perls/
job 28 at Wed Apr  18 18:00:00 2001

What system users/groups get assigned to the scheduled process? What attributes of the job submission environment are preserved and carried over into the job execution environment? Discovering how a utility provides a service behind the curtains is usually not of interest to most users. In the case of at, however, an actual example of what the utility does is fairly simple to follow and shows what's possible, what isn't and why. Every scheduled job results in a generated Bourne shell script placed under the /var/spool/at/ directory. These generated scripts are comprised of the following sections:

  • Program comments that provide some clues as to which user is notified when the job completes. Also, the effective user and group ID assigned to the job is specified.

  • umask setting dictates how new files/directories should be created.

  • A full listing of environment variable assignments at the time the job was submitted (except those related to display devices, such as TERM and DISPLAY).

  • The current directory changes to where the user was when the task was scheduled. If that directory does not exist when the job executes, the job aborts and an e-mail notification is sent.

  • An appended copy of the program text that was submitted to at.

With this in mind, Listing 1 is an abbreviated example of a script generated on behalf of a job scheduled by our user Moe. To complete our command-line interface description of the at program, see Table 2 for some of its more useful command-line options.

Listing 1. Sample—Moe's Job

Table 2. Command-Line Options

The following is another example of scheduling a job with at:

$ at -mf /home/curly/shells/program1  6pm tomorrow
warning: commands will be executed using /bin/sh
job 29 at Thu Apr  12 18:00:00 2001

Two other programs are tied to the basic at program: atq and atrm. As you might guess, atq lists jobs currently scheduled while atrm cancels one or more specified jobs. While the root user is capable of viewing and canceling any and all jobs, nonroot users can only view and cancel what they schedule.

Listing 2 shows an example of the output displayed by atq, as viewed by the root user (I inserted the field labels for better readability—unfortunately the Linux implementation of atq does not provide them).

Listing 2. Sample atq Output

Rank is a unique sequence value used to identify scheduled jobs to other at programs. In addition to the scheduled time and the submitting user, a queue value is listed. Unless the user specified otherwise, jobs are placed on the “a” queue. (Reference the on-line manual page for the implications of specifying an alternate queue value to the at program—it essentially controls the runtime priority of the job.) atq qualifies currently running jobs with a “=” value in the queue field. So job 17, seen in Table 3, is currently executing.

What if a user submits a job and then realizes either the time and/or program is incorrect? The atrm utility can be used to remove one or more scheduled jobs. For example, the root user could cancel the first and second jobs listed in Table 3 with the following command:

atrm 18 19

atrm provides no feedback. A subsequent atq listing would then display a queue like the one in Listing 3.

Listing 3. Revised Sample atq Output



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Use a real job scheduling system !

Dieter Stubler's picture

Cron and At are usefull for very basic taks only.

To get real control over your jobs ans batches u should consider using a real enterprise job scheduling system.

have a look at our companies license free bicsuite job scheduling system

Our Site is German only but answer your question in english or dutch as well


Apache user not able to use at

Anonymous's picture

When executing from php, like:

exec('echo "echo -n \'bddasddasasddsaody \' | /bin/mail -s \'get the train\' toni ^d" | at 11:30 Today');

Then sends me a mail with an error message:

From apache@localhost.localdomain Wed Oct 11 11:24:00 2006
Date: Wed, 11 Oct 2006 11:24:00 +0900
From: Apache apache@localhost.localdomain
Subject: Output from your job 128
To: apache@localhost.localdomain

usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-i identity_file] [-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-w tunnel:tunnel] [user@]hostname [command]

What am I doing wrong?!

Re: Take Command: At Your Service--Job Scheduling for Linux

DrScriptt's picture

Another very good article. I did however notice the lack of one thing that I normally see when people are referring to at vs cron. I usually see some mention of the fact that at is a one time job run, where as cron is a recurring job run. Other than that, very good. Users should be able to deduce that though. Still a very good informative column.

I like these types of articles. I tend to read them before I get started on a project as a way to procrastinate. (shame on me) The point being the articles take 10 - 15 minutes to read and play with. In that time users can learn things that will make their job easier.


Re: Take Command: At Your Service--Job Scheduling for Linux

Anonymous's picture

Hi - FYI, the following annotation addressed the comparison
of AT and CRON ...

Thanks much for the positive feedback.

--- Louis Iacona