hpr4637 :: UNIX Curio #6 - at and batch

Running a non-interactive job at a particular time, or just now

Hosted by Vance on Tuesday, 2026-05-12 is flagged as Clean and is released under a CC-BY-SA license.
unix curio, unix, at, batch, cron. 4.

Listen in ogg, opus, or mp3 format. Play now:

Duration: 00:11:06
Download the transcription and subtitles.

general.

This series is dedicated to exploring little-known—and occasionally useful—trinkets lurking in the dusty corners of UNIX-like operating systems.

I would imagine that most users of UNIX-like systems have heard of cron —certainly any system administrator should have. Briefly, cron is a way of running a job repeatedly based on the time and date; for example, a job could run every hour, at 5:00am every Tuesday, or the 3rd of every month. It is commonly used for administrative or maintenance tasks that should be done on a regular schedule, such as checking for software updates, rotating log files, or updating the database for the locate command.

As well-known as cron is, there is a similar utility that very few seem to be aware of: at . This is the word "at", and has nothing to do with the at symbol "@". An at job is very much like a cron job, except that an at job only runs one time. A job is submitted by running at timespec 1 , where timespec is the time and date the job is to be run. The linked POSIX specification page describes acceptable formats for timespec ; some examples are " now ", " 14:00 ", " noon tomorrow ", " 14:00 + 3 months ", and " 14:00 January 19, 2038 ". The utility then waits on standard input for you to enter a set of commands to be run in the job. You end input by typing Control-D to mark the end of text. (As an alternative to typing in the job, you could instead use the "<" symbol to redirect standard input to come from a file containing the commands you want to run.)

When the specified time arrives, the job will be run. That is the theory, anyway, but some things may interfere. The normal configuration for some implementations only checks for due at jobs every five minutes, so there can be a delay before a job is actually run. Also, if the system isn't running, obviously it can't execute any jobs. When it comes back up, typically it will check for any pending at jobs that are currently or past due and run those. It is best to think about an at job being run no earlier than the time it was scheduled for, and probably soon after, provided the system is up. The POSIX standard doesn't specify anything about when jobs are actually run, just that they are scheduled for a particular date and time.

The user does not need to be logged in for a job to run—if the job outputs anything to standard output or standard error, that text will be e-mailed to the user, presuming the system is set up to send mail. This is often true for a server, which might be running a Mail Transfer Agent like sendmail , postfix , or exim , but many desktops are not. If nothing is output to standard output or standard error, or if that output is redirected to a file, then mail will not be sent on job completion. This behavior can be changed with the -m option; in that case, mail will always be sent when the job finishes whether or not there is any output.

The batch command is very similar 2 —POSIX specifies it as being equivalent to at now with two differences. First, jobs are put into a different queue, and second, mail is always sent when a job completes as if the -m option was used with at . In practice, however, certain aspects of the behavior of batch depend on the implementation.

On the large majority of systems I investigated 3,4,5,6,7,8 , but not all 9 , batch jobs will only be run when the system load level drops below a certain point. This can typically be configured by the administrator but has a default value—the manual pages for a couple systems don't actually list a default value and just say batch jobs will run "when system load levels permit". Basing execution on the load level makes sense if the batch utility is seen as a way of running potentially resource-intensive jobs when the system is not being heavily used. However, this behavior is not required by POSIX.

Another question that the standard leaves unanswered is how queues behave. From the normal understanding of the word "queue", you might expect that each successive job is run one at a time once the previous job completes. However, this is not stated in POSIX, and some implementations explicitly allow a configurable number of jobs to run simultaneously. Manual pages for other systems simply don't mention the subject. (I researched this episode by looking at documentation for a number of BSD, Linux, and commercial UNIX systems, but didn't actually test out how they behave.) POSIX only requires systems to have two queues, one named "a" for at jobs and one named "b" for batch jobs, but allows implementations to have more. It says nothing about how different queues compete for resources—one implementation assigns a higher nice value to jobs in a queue whose name comes later in the alphabet, giving them a lower priority in the process scheduler.

So what good are at and batch ? While I think they certainly meet the "obscure" requirement for a UNIX Curio, I have to admit they aren't particularly useful today. They were designed for an era where a typical UNIX-like system would run around the clock and had multiple users who might log in at various times of the day but weren't connected 24/7. In that context, using batch to run a job when the system is lightly loaded might be useful; nowadays, you can just run it whenever you like on your own machine. I have never actually used batch myself. On a machine where there is serious competition for resources among users, batch is probably not a sophisticated enough tool to manage their jobs—the NetBSD and Debian manual pages explicitly suggest using something different 3,6 . Supercomputing environments have even more complex requirements and a number of specialized solutions exist for scheduling jobs there.

I have used at a couple of times. One example was for an organization I was part of that had paid for its domain name registration several years into the future. On the organization's server, I set an at job to e-mail the administrator a reminder to renew it a few months before the domain was due to expire. It was useful in that case because I didn't know whether I would even continue to be involved then, so a personal reminder for myself wouldn't necessarily help. But in my experience, administrative tasks don't tend to be one-off events. Instead, they repeat, making cron the right tool to use. For reminders, a calendar app is probably a better solution in most cases.

While you might never have a use for at and batch , I still think it's good to know that they exist. Just be aware that you'll probably need to read the manual page on your system to fully understand how they will behave.

References:

  1. At specification https://pubs.opengroup.org/onlinepubs/009695399/utilities/at.html
  2. Batch specification https://pubs.opengroup.org/onlinepubs/009695399/utilities/batch.html
  3. NetBSD 10.0 at manual page https://man.netbsd.org/NetBSD-10.0/at.1
  4. FreeBSD 15.0 at manual page https://man.freebsd.org/cgi/man.cgi?query=at&sektion=1&manpath=FreeBSD+15.0-RELEASE+and+Ports
  5. OpenBSD 7.8 at manual page https://man.openbsd.org/OpenBSD-7.8/at.1
  6. Debian 13 at manual page https://manpages.debian.org/trixie/at/at.1.en.html
  7. openSUSE 42.3 at manual page https://man.freebsd.org/cgi/man.cgi?query=at&sektion=1&manpath=openSUSE+42.3
  8. HP-UX Reference (11i v3 07/02) - 1 User Commands A-M (vol 1) https://support.hpe.com/hpesc/public/docDisplay?docId=c01922490&docLocale=en_US
  9. OpenSolaris 2010.03 at manual page https://man.freebsd.org/cgi/man.cgi?query=at&sektion=1&manpath=OpenSolaris+2010.03

Apologies for the "tapping" sound that occurs in parts of this episode. I think my microphone must have picked up some electromagnetic interference.


Comments

Subscribe to the comments RSS feed.

Comment #1 posted on 2026-05-13 03:43:37 by candycanearter07

still useful!

IMO, at and batch still have plenty of uses in things like scripts. It does provide a POSIX way to schedule a task in the future, which could be useful for scripts that want to offset certain effects without having to run its own daemon. Something like batch could also be used with cron as a sort of "run at some point after this time" trick, so if you happen to be doing something intensive at that time then it can put it off until its more optimal.

Also, at can just be used to plain run some process a few hours from now, its pretty useful for like starting an intensive process overnight without having to remember to start it before going to bed

Comment #2 posted on 2026-05-16 19:41:04 by norrist

at for scheduled reboots

I use at to schedule reboots for systems that have kernel updates installed, but I dont want to reboot right now.

Something like:
@midnight ENTER
reboot ENTER
CRTL-d

Comment #3 posted on 2026-05-17 03:03:47 by Vance

Good points

Nice to hear that others find "at" to be helpful! Perhaps some of these curios are not as obscure as I thought.

To delay running something on a personal system, I would probably be more likely to use "sleep [time] ; [command]" as a quick-and-dirty method. This would also put the output in the same terminal session. But I can see how "at" could be more elegant.

For rebooting, a lot of systems have the "shutdown" command (in looking around, it's far more common than I expected). This takes a time argument for when to execute the shutdown. So you could also use "shutdown -r 00:00" as a way to reboot your system at midnight (some implementations might differ on how the time is expressed). As with Perl, in the UNIX world often there's more than one way to do it!

Comment #4 posted on 2026-05-17 18:35:11 by Whiskeyjack

At and batch in HPR4637

I happen to have a number of VMs set up that I use for testing, so I was able to do a quick check to see which distros have "at" and "batch" installed by default.

It turns out that Debian, Ubuntu, Raspberry Pi, Suse, and Alpine do not have it by default. Alma (a Red Hat clone), FreeBSD, and OpenBSD do.

While they can be installed later, it may be that they are not more commonly used now because you cannot rely on them being there as a standard feature.

I was struck by the thought that "batch" may be useful for things like testing software by being able to kick off a long series of tests that are run in the background while you get on with doing other things without these background tests affecting whatever else you are doing too much. Audio and video processing may possibly be the same.

Perhaps some other listeners could think up some creative ways of using "at" and "batch" and tell us about it in an episode in future. This sounds like it could lead to some interesting ideas.

Leave Comment

Note to Verbose Commenters
If you can't fit everything you want to say in the comment below then you really should record a response show instead.

Note to Spammers
All comments are moderated. All links are checked by humans. We strip out all html. Feel free to record a show about yourself, or your industry, or any other topic we may find interesting. We also check shows for spam :).

Provide feedback
Your Name/Handle:
Title:
Comment:
Anti Spam Question: What does the letter P in HPR stand for?