| If you don't know how to create the script that cron or at will call, see New To Unix |
These three commands are used to run commands at some other time. They differ in their usage, their environment, and their default actions, so are sometimes a source of confusion. If you are having trouble with cron, you might want to read Cron is not working first.
The "batch" command really just calls at with special flags set:
at -q b -m now
but "cron" is truly a totally separate command.
One of the common problems posted to the Unix newsgroups goes something like:
I have a command script. If I run it from the command line or
with "at", it works, but if I run it with "cron" it fails. Why?
Not only is this a common question, but amazingly enough, it usually generates three or four wrong answers every time it appears. The correct answer is that it fails because "cron" runs with a different environment than what you have. You have a certain PATH, you have other environment variables set, and "at" deliberately notices all that and makes sure that when your command runs, all those things will be in place. The "cron" utility does not: it has its own environment, probably very different from yours.
Very often, it's just the PATH that is different. For example, root's environment usually has
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11
but cron's default environment is set to to
PATH=/usr/bin:/bin
That's normal for most Unix systems, but don't trust it absolutely. I've seen systems (old SCO boxes) where the man page said that but the actual PATH was different. On any system, cron's PATH is unlikely to be the same as what it is when you are logged in, so your scripts may have to be explicit to work (or you can set the desired PATH in the crontab).
The other likely cause for failure is a missing environment variable. Cron has:
HOME=/root (or the home directory of the user whose job is running)
IFS='
'
LANG='en_US.UTF-8'
LOGNAME='root'
OPTIND='1'
PATH='/usr/bin:/bin'
PPID='14364'
PS1='# '
PS2='> '
PS4='+ '
PWD='/root'
SHELL='/bin/sh'
Linux cron has the very nice feature of being able to set environment variables directly in the crontab file ( see man 5 crontab on a Linux system). But don't make the mistake of exporting them. This doesn't work in crontab:
FOO=xyz;export FOO
That would end up with your scripts seeing FOO as "xyz;export FOO" rather than the "xyz" you wanted. You don't need to worry about export anyway; cron will do that automatically.
It also allows you to control who mail is sent to when the commands generate output, or to have no mail sent at all (MAILTO=""). That saves you from having to redirect output if you don't care about anything the script has to say. Linux crontab files are found in non-standard (non-standard for Unix) places, so you should read the man pages ( or "info cron" ) carefully- it's a bit different than Unix. Also, some of the files have an extra argument: files put in /etc/cron.d specify a user before the command to be run. Don't forget that, or they won't work. And of course files in /etc/cron.daily (hourly, etc.) are just scripts that are called by "run-part"entries in /etc/crontab. Note that /etc/crontab also requires that extra "user" field. If you run "crontab -l", you'll be listing files from /var/spool/cron, and these are familiar Unix format.
If your command script requires anything variables not in cron's normal environment and not otherwise set (in the script or in a Linux crontab file), it will fail. If your script required Korn shell features, it would also fail if the feature required doesn't work in Bash.
A simple way to fix the environment issue is to read your environment into the crontab. You can, for example, type ":r!set" if using "vi".
Recently someone asked me why their crontab wasn't working. They
understood that they needed to set their environment, but what they
did was something like this:
17 5 * *
* ./setmyenv.cmd;domystuff.cmd
That'll never work, and wouldn't work from the shell either. You would need to add a ". ./setmyenv.cmd" inside "domystuff" (that's dot space dot slash setnyenv.cmd).
On Linux you can edit crontab files directly and cron will notice that you have changed them. Most Unixes don't do that and you'll often see advice to use "crontab -e". That works, but a more safe procedure is:
crontab -l > /tmp/mycrontab
vi /tmp/mycrontab (make your changes)
crontab /tmp/mycrontab
Or, if for another user:
crontab -u john -l > /tmp/mycrontab
vi /tmp/mycrontab (make your changes)
crontab -u john /tmp/mycrontab
Be careful with crontabs set to other users. Remember that cron cd's to the user's directory when it starts up your job. If the user's directory doesn't exist cron fails and sends mail to that user.
The "at" and "batch" programs are much less complex. Batch takes no arguments; it just runs your program. The details of these are covered in the man pages.
Enter your email address for automatic notification of new posts here
(be sure to whitelist 'feedburner.com' if you use spam filtering)
| Views for this page | ||||
|---|---|---|---|---|
| Today | This Week | This Month | This Year | Overall |
| 2 | 35 | 114 | 1,891 | 3,791 |
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.

Add your comments
Lone-Tar Backup and Disaster Recovery
for Linux and Unix