August 15, 2005

CLI Magic: At tricks

Are you looking for a reliable scheduler to help you automate your processes? You may not realize it, but you have a useful command-line tool for scheduling jobs at your fingertips -- at.

at does exactly what it sounds like -- it does a job at a set time. For instance, the command who > /tmp/who-list.tmp | at 16:30 September 1 will run who, save the output in a file (/tmp/who-list.tmp), and do it at 16:30 on September 1 of the current year. If you want to run it for a future year, you can specify the year on the command line after the day of the month. When you invoke it, at will assign a job number and will confirm the details to the screen:

job 412345 at 2005-09-01 16:30

You can also schedule work by calling at from the command line, typing in the details of the work to be carried out, and then pressing Ctrl-D to exit:

at 16:30 September 1
who > /tmp/who-list.tmp
Ctrl-D

If you happen to type in a time that has passed (e.g. typing in 16:30 when it is actually 16:35), at will execute the commands immediately.

You can also save your commands to a file and then submit your file to at:
at 16:30 September 1 or cat myfile | at 16:30 September 1

at lets you schedule tasks to run at noon or midnight, today or tomorrow, using those keywords. Best of all, if you want to run your commands at 16:00, use at teatime. How more civilized can you get?

If you don't like using the 24-hour format, at is just as happy using a.m. and p.m.; at 9 AM September 1 is the same as at 09:00 September 1.

Along with absolute dates and times, you can also define relative times by using a plus-sign along with the keyword minutes, hours, days, or weeks, as in at teatime tomorrow + 1 week. You can't use seconds. at is, however, very obliging about whether you use plurals or not; it's fine to say at 09:00 September 2 + 7 hours. You can also use the now statement, as in at now + 3 hours. If you do make a mistake, at will return the error Garbled time.

at decides who can schedule jobs according to the contents (or absence) of two file -- /etc/at.allow and /etc/at.deny. If /etc/at.allow exists then only users listed in it may create new jobs. If the file doesn't exist then at will look for the file /etc/at.deny and will stop any users listed there from creating schedules. If neither file exists then only root may use at. By default most system have an empty /etc/at.deny file, meaning that all users may use at.

Standard outputs and errors
One concern with using at is that any standard outputs or errors from your commands are not returned to the terminal, but instead are emailed to you. If you don't want that to happen, then either ensure that outputs are redirected to a log file with a command such as date 2>&1 >> ~/logfile, or turn them off altogether: do_any_command 2>&- 1>&- If you want to receive the emails but not to your Linux desktop, create a file ~/.forward, edit the file, and type in the email address that the mails should go to.

Checking what at's up to

So you've been busy setting up your schedule -- but how do you know what's going to run and when? If you use the command at -l or atq and if there are jobs waiting to be run, you will see the command return something like:

4123418      2005-08-10 16:00 a bainm
4123415      2006-06-01 16:30 a bainm

In this example there are two jobs waiting to run -- job numbers 4123415 and 4123418, both owned by user bainm (you will see only your own jobs listed; to see all jobs you must log on as root). However, although you can see that there are jobs to be run, and you can see when they are due to run, there is nothing to tell you what the jobs are actually going to be. To see the details of each job you must look in the directory /var/spool/atjobs -- but this not usually accessible by most users.

In this directory are a number of at-related files -- one for each job waiting to be processed -- though it can be difficult to work out which file relates to which job.

If you need to remove a job, and you're able to work out which job it is that you need to delete, then use the command at -d or atrm, as in at -d 4123418 or atrm 4123418 to remove job number 4123418.

Click Here!