Linux Help on cron 

http://www.csun.edu/helpdesk/linux.htm

Getting started with cron 

The cron daemon is a truly nifty thing. Throughout the day (and night, if you leave your system running), it wakes up every minute, and checks /etc/crontab to see whether it needs to perform any tasks. If so, the utility executes them. It's as if you had a properly-trained robot typing commands at your keyboard. Cron is ideal for tasks that need to be carried out regularly—performing incremental backups is definitely one of them.

The cron daemon consults lots of system-level files, including several in /etc/cron, but each user can set up an individually tailored cron. To create your own cron, you'll need to use the crontab utility, which lets you create the crontab file and then installs this file correctly.

To create the crontab file, you need to type a command line. The syntax is simple. The first five fields of the line, separated by spaces, correspond to the following times:

If you type an asterisk in one of these fields, it means "all the times for this field." Following the five time fields is a command, just as if you'd type it at the keyboard. Here's an example: 15 * * * * echo "Hello, there"

This command tells cron to send the message "Hello, there," every fifteen minutes. Here's another example:

0 6 * * * smbmount //rivendell/backup /home/bryan/backup -N

This command tells cron to execute the smbmount command every morning at 6:00 A.M. sharp.

To create a crontab file, log in using your ordinary user account, type cronttab -e, and press [Enter]. You'll see your default editor. Type the crontab commands you want to use, and exit the editor. Crontab will create your crontab file, and update your system so that the commands execute at the times you specified.

Scheduling automatic backups with cron 

If you've learned the basics of the cron daemon and the crontab utility, you can use cron to schedule automatic incremental backups with the tar utility, as described in "Develop a backup routine" (Mar. 23, 2000). Here's the command to perform an automatic, incremental backup of an entire home directory (/home/bryan, in this example); note that this command is scheduled to run late every night, to be precise. (In case you've forgotten, cron commands begin with five time fields, corresponding to minute, hour, day of month, month, and day of week.)

59 23 * * * tar -uf /home/bryan/backup/backup.tar /home/bryan

The tar command updates the archive (backup.tar) with all the files that have been created or modified since the last incremental backup occurred.

More cron tricks: Time ranges 

You can also specify time ranges with cron. To specify a list of times, specify them in a comma-separated list:

0 15,18,23 * * * rm /home/suzanne/core

This command removes core files from the specified directory at 3, 6, and 11 P.M. (the times are indicated using the 24-hour military clock).

To specify a range of times, use a hyphen. The following runs the specified tar command Monday through Friday, but gives tar a break on weekends:

To configure the user's cron settings, use crontab with the -e switch (crontab -e).

cmd:Vixie 

What's Vixie, you wonder? It's a nifty addition to the cron system, and it's installed by default with most Linux distributions (NB, default in RedHat and Debian). To find out whether you've got Vixie, take a look at your /etc directory; if you see directories such as /etc/cron.hourly, /etc/cron.daily, and so on, you've got Vixie.

And what does Vixie do? Essentially, Vixie is a scripting interface to cron. Vixie does its magic with a script called run-parts, which lives by default in the /usr/bin directory. This script looks for special commands in /etc/crontab, the system administrator's cron configuration file. These commands tell the run-parts script which directory to look in. At the specified time, the script examines this directory and executes all the scripts it finds.

Take a look in the /etc/crontab.* directories. Chances are you'll find lots of these scripts. If you add additional scripts to these directories, Vixie will execute them at the interval specified by the directory name (such as /etc/crontab.weekly) and the specific time given in /etc/crontab.

Putting a skeleton in every user's closet 

When you create a new user for your Linux system, most of the utilities used for this purpose (including Linuxconf and adduser) automatically create a new home directory for the user. What's more, these utilities also copy to the new home directory all the files that are found in /etc/skel. If you add files to those found in this directory, or change the files found in this directory, your additions and changes will automatically appear in every new user's directory. For example, suppose you'd like to give every user the benefit of a custom bash prompt you've devised. If you make the needed changes to the bash configuration files, every new user will see the customized bash prompt instead of the default. Note, however, that changes to /etc/skel don't affect existing directories; you'll have to change those manually.

cmd:crontab 

Usage 

Linux 

cron jobs 

In RH, cron jobs are not only in crotab, but also in /etc/cron.daily, etc.

/etc/cron.daily$ ls
00-logwatch  logrotate        slocate.cron  tmpwatch
00webalizer  makewhatis.cron  sysstat       tripwire-check
0anacron     rpm              tetex.cron

In short, use /etc/cron.* or /etc/cron.d for systerm cron task. For personal cron jobs, use crontab still.

Get 
crontab -l | tee /dev/tty | tail  +2 > /export/sysbaks/crontab.$USER.$HOST
dir !$
cat !$
Verify 

Verify the (- installed on …) line

Set 
crontab -r
% crontab -l
no crontab for root
tail +3 /export/sysbaks/crontab.$USER.$HOST | crontab -
crontab -l

Solaris 

USER=root
echo $USER.$HOST
Get 
crontab -l | tee /dev/tty > ~/s/tmp/crontab.$USER.$HOST
es !$
Set 
crontab ~/s/tmp/crontab.$USER.$HOST; crontab -l
Verify 
crontab -l | diff ~/s/tmp/crontab.$USER.$HOST -

Configuring a Cron Task in RedHat 

http://www.redhat.com/docs/manuals/linux/RHL-7.2-Manual/custom-guide/cron-task.html

The main configuration file for cron, /etc/crontab, contains the following lines:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

The first four lines are variables used to configure the environment in which the cron tasks are run. The value of the SHELL variable tells the system which shell environment to use (in this example the bash shell), and the PATH variable defines the path used to execute commands. The output of the cron tasks are emailed to the username defined with the MAILTO variable. If the MAILTO variable is defined as an empty string (MAILTO=""), email will not be sent. The HOME variable can be used to set the home directory to use when executing commands or scripts.

Each line in the /etc/crontab file has the format:

minute hour day month dayofweek command

For any of the above values, an asterisk (*) can be used to specify all valid values, which always stands for “first-last”. For example, an asterisk for the month value means execute the command every month within the constraints of the other values.

A hyphen (-) between integers specifies a range of integers. For example, 1-4 means the integers 1, 2, 3, and 4.

A list of values separated by commas (,) specifies a list. For example, 3, 4, 6, 8 indicates those four specific integers.

The forward slash (/) can be used to specify step values. The value of an integer can be skipped within a range by following the range with /<integer>. For example, 0-59/2 can be used to define every other minute in the minute field. Step values can also be used with an asterisk. For instance, the value */3 can be used in the month field to run the task every third month.

Any lines that begin with a hash mark (#) are comments and are not processed.

Example: Example 22-1. Examples of crontabs
# record the memory usage of the system every monday
# at 3:30AM in the file /tmp/meminfo
30 3 * * mon cat /proc/meminfo >> /tmp/meminfo
# run custom script the first day of every month at 4:10AM
10 4 1 * * /root/scripts/backup.sh

As you can see from the /etc/crontab file, it uses the run-parts script to execute the scripts in the /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly files on an hourly, daily, weekly, or monthly basis respectively. The files in these directory should be shell scripts.

If a cron tasks needs to be executed on a schedule other than hourly, daily, weekly, or monthly, it can be added to the /etc/cron.d directory. All files in this directory use the same syntax as /etc/crontab, which are in a different format than those 'crontab -e' files.

The cron daemon checks the etc/crontab file, the etc/cron.d/ directory, and the /var/spool/cron directory every minute for any changes. If any changes are found, they are loaded into memory. Thus, the daemon does not need to be restarted if a crontab file is changed.

Users other than root can configure cron tasks by using the crontab utility. All user-defined crontabs are stored in the /var/spool/cron directory and are executed using the usernames of the users that created them. To create a crontab as a user, login as that user and type the command crontab -e to edit the user's crontab using the editor specified by the VISUAL or EDITOR environment variable. The file uses the same format as /etc/crontab. When the changes to the crontab are saved, the crontab is stored according to username and written to the file /var/spool/cron/username.

crontab format 

Blank lines and leading spaces and tabs are ignored. Lines whose first non-space character is a pound-sign (#) are comments, and are ignored. Note that comments are not allowed on the same line as cron commands, since they will be taken to be part of the command. Similarly, comments are not allowed on the same line as environment variable settings.

Starting and Stopping the Service 

To start the cron service, use the command /sbin/service crond start. To stop the service, use the command /sbin/service crond stop. It is recommended that you start the service at boot time. Refer to Chapter 8 for details on starting the cron service automatically at boot time.

Help 

man crontab
man 5 crontab
$ crontab
usage:  crontab [-u user] file
       crontab [-u user] { -e | -l | -r }
               (default operation is replace, per 1003.2)
       -e      (edit user's crontab)
       -l      (list user's crontab)
       -r      (delete user's crontab)

The first form of this command is used to install a new crontab from some named file or standard input if the pseudo-filename “-” is given.

The -e option is used to edit the current crontab using the editor specified by the VISUAL or EDITOR environment variables. After you exit from the editor, the modified crontab will be installed automatically.

crontab tables 

Help 

cron(8) examines cron entries once every minute.

The time and date fields are:

field          allowed values
-----          --------------
minute         0-59
hour           0-23
day of month   1-31
month          1-12 (or names, see below)
day of week    0-7 (0 or 7 is Sun, or use names)

A field may be an asterisk (*), which always stands for “first-last”.

Ranges of numbers are allowed. Ranges are two numbers separated with a hyphen. The specified range is inclusive. For example, 8-11 for an “hours” entry specifies execution at hours 8, 9, 10 and 11.

Lists are allowed. A list is a set of numbers (or ranges) separated by commas. Examples: “1,2,5,9”, “0-4,8-12”.

Step values can be used in conjunction with ranges. Following a range with “/<number>” specifies skips of the number's value through the range. For example, “0-23/2” can be used in the hours field to specify command execution every other hour (the alternative in the V7 standard is “0,2,4,6,8,10,12,14,16,18,20,22”). Steps are also permitted after an asterisk, so if you want to say “every two hours”, just use “*/2”.

EXAMPLE CRON FILE 
# use /bin/sh to run commands, no matter what /etc/passwd says
SHELL=/bin/sh
# mail any output to `paul', no matter whose crontab this is
MAILTO=paul
#
# run five minutes after midnight, every day
5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * *     $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5   mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun     echo "run at 5 after 4 every sunday"

Cron jobs testing 

From http://www.redhat.com/docs/manuals/linux/RHL-7.2-Manual/custom-guide/cron-task.html

,-----
| The cron daemon checks the etc/crontab file, the etc/cron.d/
| directory, and the /var/spool/cron directory every minute for any
| changes. If any changes are found, they are loaded into
| memory. Thus, the daemon does not need to be restarted if a crontab
| file is changed.
`-----

Here is an example showing how add an entry to etc/cron.d/ using symlinks.

create a file /path/to/sysbak.cron:

# one minute interval testing
* * * * * root /path/to/sysbak.sh test

and in /path/to/sysbak.sh:

MAILTO=tong
echo "Unknown option passed to $0: '$1'"

Then created a symlink:

ln -sf /path/to/sysbak.cron /etc/cron.d/

That's it. Watch the syslog with

tail /var/log/syslog

Then check the email.

Cron jobs testing 

Newsgroups: comp.os.linux.misc,comp.os.linux.admin,linux.redhat.misc Date: Tue, 25 Feb 2003 19:25:10 GMT

Support for crontabs under /etc/cron.d is flaky at best, often being undocumented and/or broken.

Robert Tinsley

Cron jobs testing 

>> I added an entry to etc/cron.d/ but why it doesn't get executed?
>
> You shouldn't do that. You should run "crontab -e" as the user who is
> going to execute the scheduled task.

Does crontab -e diddle the /etc/crontab file though? I always edit that one myself with emacs. I am not pushing emacs here: use whatever text editor you like. (I seldom need to edit /etc/crontab except when installing a new release or something.)

Jean-David Beyer

Cron jobs testing 

> you shouldn't edit /etc/crontab at all. that file is just an evil, nasty
> hack put in by red hat so that they could implement /etc/cron.daily (and
> friends) in some totally non-standard way.

SuSE is using /etc/crontab too. I like it, if you have multiple cron jobs running as different app user, it's more pleasant (for me) to have them in a single file.

Michael Heiming

cron jobs without mailing 

Newsgroups:  gmane.linux.debian.user
Date:        Sun, 26 Sep 2004 12:20:56 -0700
> To update my webpages from CVS I use a crontab with some jobs. But every
> time the jobs are executed at sourceforge.net I get a mail. This seems
> to be the default behaviour. Is there a possibility to disable this
> mailing?

IIRC cron only mails when there is output.

Put '>/dev/null 2>&1' at the end of the command in your sf.net crontab.

Stefan O'Rear

cron jobs without mailing 

> IIRC cron only mails when there is output.
>
> Put '>/dev/null 2>&1' at the end of the command in your sf.net crontab.

You can disable all cron mail by setting 'MAILTO=""' in your crontab. See 'man 5 crontab' for details.

Patrick

Limitation of cron 

http://thread.gmane.org/gmane.linux.debian.user/319121/focus=319134

Subject: What's the problem with this cron command
Newsgroups: gmane.linux.debian.user
Date: 2008-03-15

Hi,

Please take a look at the following cron task:

 * * * * *      root    ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' > /dev/null || logger get executed.

It bewilders me that it is not doing what I want. Here is the syslog when it is run:

 Mar 15 13:15:02 cxmr /USR/SBIN/CRON[22779]: (root) CMD (ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao
*write|growisofs.*speed=' > /dev/null || logger get executed.)
 Mar 15 13:15:02 cxmr /USR/SBIN/CRON[22780]: (root) CMD ...

I.e., I want to execute a cron task if I'm not burning CD/DVD. But the actual command never get executed, even when I'm not burning CD/DVD. If I redo the command from the command line, it is fine:

$ (ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' > /dev/null || logger get executed.)
$ tail /var/log/syslog
Mar 15 13:16:27 cxmr tong: get executed.

So, what is the problem?

PS. I'm sure the PATH is setup properly in my cron, so cron can find ps & grep.

xpt

Limitation of cron 

Subject: Re: cron and command quote
Newsgroups: gmane.linux.debian.user
Date: 2008-03-17

On Sun, 16 Mar 2008, NN_il_Confusionario wrote:

> > * * * * *  root    ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao
> > *write|growisofs.*speed=' > /dev/null || logger get executed.
> > PS. I'm sure the PATH is setup properly in my cron, so cron can find ps
> > & grep.
>
> You could, for debugging pourposes:
> * look at mails that cron sends if a commnd give any output;
> * replace temporarilly the command with
>   set -x;echo $PATH;which ps;which grep;which find;which logger;ps -eaf | grep -E ...
> * replace the command with a shell script which executes the command in a shell
>   with set -x and/or other shell debugging options; for example also
>   temporarilly drop redirection to /dev/null

Thanks a lot. With your suggestion, I found the reason — it is as people (e.g. Raj) have suspected, it's problem of cron and quotes.

Here is the execute log:

 Mar 17 17:28:01 cxmr /USR/SBIN/CRON[26757]: (root) CMD (set -x;which ps;which grep;ps -eaf | grep -E
'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' || logger get executed.)

The mail that I got says:

 + which ps
 /bin/ps
 + which grep
 /bin/grep
 + ps -eaf
 + grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
 root     26757 26756  0 17:28 ?        00:00:00 /bin/sh -c set -x;which ps;which grep;ps -eaf | grep -E 'cdrecord.*
-[dts]ao |cdrdao *write|growisofs.*speed=' || logger get executed.
 root     26761 26757  0 17:28 ?        00:00:00 grep -E cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=

I.e., somehow, the 'ps | grep' was able to find something in cron, whereas when executed directly under shell:

$ ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
$ /bin/sh -c "ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='"

I.e., if the same command are executed directly under shell the 'ps | grep' finds nothing.

Anyone can give some explanation?

xpt

Limitation of cron 

On Tue, 18 Mar 2008, s. keeling wrote:

>>  I.e., somehow, the 'ps | grep' was able to find something in cron, whereas
>>  when executed directly under shell:
>>
>>   $ ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
>>
>>   $ /bin/sh -c "ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='"
>>
>>  I.e., if the same command are executed directly under shell the
>>  'ps | grep' finds nothing.
>>
>>  Anyone can give some explanation?
>
> Yes.  you're stressing either the tool, or your knowledge of it.  Put
> the relevant bits in a shell script and tell cron to execute that.
> Then you'll have full control.  It won't be hampered by cron's (by
> design) limitations.

Nope, that didn't work. Thanks for the suggestion though s. keeling.

Here is what happened after I followed the above advice.

Now the crontab reads:

 * * * * *      root    is_burning || logger get executed.

The mail that I got says:

+ set -x
+ ps -eaf
+ grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
root     15306 15295  0 09:29 ?        00:00:00 grep -E cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=
+ exit 0

when executed directly under shell:

$ is_burning || echo not burning CD/DVD
not burning CD/DVD

I.e., having put the 'ps | grep' part into a shell script, the behavior is still the same.

xpt

[Solved] grep and cron & command line 

On Tue, 18 Mar 2008, Bob McGowan <at> symantec.com wrote:

>> Now the crontab reads:
>>
>>  * * * * *    root    is_burning || logger get executed.
>>
>> + set -x
>> + ps -eaf
>> + grep -E  -[dts]ao |cdrdao *write|growisofs.*speed='
>> root     15306 15295  0 09:29 ?        00:00:00 grep -E cdrecord.*
>> -[dts]ao |cdrdao *write|growisofs.*speed=
>> + exit 0
>>
>> $ is_burning || echo not burning CD/DVD
>> not burning CD/DVD
>>
>> I.e., having put the 'ps | grep' part into a shell script, the
>> behavior is still the same.
>> Does it has anything to do with busybox?
>
> If I followed the above discussion correctly, the OP's concern is that
> sometimes the grep will return a result, even when the specified cd
> related programs are not running, and that this happens when the grep is
> run from cron but not from the command line.

Exactly. Right on!

> If this is correct, the results you're seeing can in fact happen in
> either case.  Whether you see a result or not is totally dependent on
> the process scheduler, timing of execution slices and perhaps your
> processor speed and/or if it's an SMP environment.
>
> What's happening is the grep you're running is sometimes finding itself.
>   For example:
>
>    ps -ef|grep firefox|cut -c1-60
>    rmcgowan 17073 16974  0 08:13 ?        00:00:00 /bin/sh /usr
>    rmcgowan 17106 17080  0 08:13 ?        00:00:59 /usr/local/f
>    rmcgowan 30742 17130  0 10:49 pts/1    00:00:00 grep firefox
>
> The last line is the grep that ran.  So, one line is sometimes returned,
> even when firefox is not running.
>
> There are a number of ways to get around the problem.  My favorite is to
> use something that will show up in the ps output for the grep itself but
> which will not be part of what you're looking for.  But this does
> require using either the -l or -f options (which it looks like you are).
>
>    ps -ef | grep '[f]irefox'
>
> will eliminate the grep command itself because the pattern can never
> match itself. . .
>
> I hope this helps solve your problem.

Bingo!!!

That's exactly the reason. As you can see from my script that I've already applied the '[]' trick, but the trick wasn't applied to all 3 grep cases. Having added '[]' to each of the grep cases, I finally see:

Mar 18 21:29:01 cxmr logger: get executed.

Bravo!!!

Thanks a lot to everyone who replied!

xpt

cron 

       Date: Fri, 27 Sep 2002 14:47:29 -0700
Newsgroups: comp.os.linux.setup, comp.os.linux.misc
>      i want a perl script to be executed every minute.
> so i setup cron like this
>
> crontab -e
>
> "0-59" * * * * /root/script.pl
>
> But it doesn't seem to be executing it.

It always helps to read the documentation.

or

0-59 * * * * /root/script.pl # one minute intervals

and, a really cool feature, for intervals other than one minute:

0-59/4 * * * * /root/script.pl # four-minute intervals
0-59/8 * * * * /root/script.pl # eight-minute intervals

Paul Lutus

sh script cron job 

I have a .sh script that I run from the command line and also put into a cron job. I need to see the output on the screen and read a generated log file.

There are a couple of ways to approach this:

1) a file like: In this case the output goes to t.log but not on the screen

#!/bin/ksh
exec 1>t.log 2>error.log>&1
printf "UNIX output displayed here\n"
ls -l
svrmgrl <<!
@$ID_DIR/vant8i_internal_id.sql;
exit
!

2) a file like: Using the tee command. But in this case I have to put

| tee -a t.log

at every command I want to see, my real file is too long.

#!/bin/ksh
printf "UNIX output displayed here\n" | tee -a t.log
ls -l|tee -a t.log
svrmgrl <<! |tee -a t.log
@$ID_DIR/vant8i_internal_id.sql;
exit
!

3) Final option. This uses the unix script command to output everything on the screen to the file t.log The script session must be terminated with a CTRL-D. The problem here is I don't know how to represent a ^D in a script. Can I execute it as an octal (004) but how?

#!/bin/ksh
script t.log
printf "UNIX output displayed here\n"
ls -l
svrmgrl <<!
@$ID_DIR/vant8i_internal_id.sql;
exit
!
^D

sh script cron job 

> The script session must be terminated with a CTRL-D.

Actually, no. Script terminates on EOF or when the child process terminates. ^D is just how *you* type EOF.

>#!/bin/ksh
>script t.log
>printf "UNIX output displayed here\n"
>ls -l
>svrmgrl <<!
>@$ID_DIR/vant8i_internal_id.sql;
>exit
>!
>^D

Imagine a script

#!/bin/ksh
cat
^D

Will this work? Of course not! "cat" doesn't read from the script - the script is being processed by /bin/ksh. "cat" reads from the script's input.

What you've just done is write a script to run script (with output to t.log)… But it runs script with no input specified, so it runs on stdin.

Try, perhaps

script t.log <<EOS
printf "hi mom\n"
ls -l
# substitute your preferred program here
cat<<EOF
blah
exit
EOF
exit
EOS

The last "exit" is because most shells terminate on exit.

sh script cron job 

Yes, this works.

documented on: 2000.05.23