Link to home
Start Free TrialLog in
Avatar of wxman1
wxman1

asked on

CRON job to run perl script

Hi all,

I've written a perl script that will do some file archiving and ftp'ing.  This script works perfectly.  It resides in the drectory /brian/

I would like to automate this script, and I have attempted to write a cron job to run every 5 minutes, executing this script.  From what I can see, this cron job should work, but it does not.  I've tried two ways, one by having the cron job run the perl script:

00,05,10,15,20,25,30,35,40,45,50,55 * * * * /brian/perlscript.pl

and also by having the cron run a shell script to execute the perl script:

00,05,10,15,20,25,30,35,40,45,50,55 * * * * /brian/run.sh

where run.sh is:
#!/bin/sh

/brian/perlscript.pl

Can anyone help?

Thanks,

Brian

Avatar of jlevie
jlevie

Cron reports its errors via mail to the user that owns the crontab. What do those error reports say?

What is the first line of /brian/perlscript.pl? Is that file executable?
Avatar of wxman1

ASKER

jlevie

I've tried to find the error mail, but I have no idea where to access it, if it helps Im running SuSe 9.1.

the perlscript is executable and the first line is
#!/usr/bin/perl

I've been able to run it as root from the rrot directory by typing /brian/perlscript.pl and I have no problems.

root owns the cron job by the way.
If it is root's cron job the errors will be in root's mail (or where ever that's been aliased to).

Did you create the cron entry with 'crontab -e'?
Avatar of wxman1

ASKER

I'm not sure I found the "right" mail, but I did find a mail under a root title, but it only listed mail from September (probably when the OS was installed).  There is nothing recent.

I created the cron by creating a file called rename.crontab, then I typed crontab rename.crontab

when I type crontab -l it displays the cron job, so it obviously has been accepted.
Check the aliases file and see if mail to root has been aliased to someone (either /etc/aliases or /etc/mail/aliases).
Avatar of wxman1

ASKER

sorry to post all of this, but I am a Linux newbie, below is my aliases file

# This is the aliases file - it says who gets mail for whom.
#
# >>>>>>>>>>      The program "newaliases" will need to be run
# >> NOTE >>      after this file is updated for any changes
# >>>>>>>>>>      to show through to sendmail.
#

# It is probably best to not work as user root and redirect all
# email to "root" to the address of a HUMAN who deals with this
# system's problems. Then you don't have to check for important
# email too often on the root account.
# The "\root" will make sure that email is also delivered to the
# root-account, but also forwared to the user "joe".
#root:          joe, \root

# Basic system aliases that MUST be present.
postmaster:     root
mailer-daemon:  postmaster

# amavis
virusalert:     root

# General redirections for pseudo accounts in /etc/passwd.
administrator:  root
daemon:         root
lp:             root
news:           root
uucp:           root
games:          root
man:            root
at:             root
postgres:       root
mdom:           root
amanda:         root
ftp:            root
wwwrun:         root
squid:          root
msql:           root
gnats:          root
nobody:         root
# "bin" used to be in /etc/passwd
bin:            root

# Further well-known aliases for dns/news/ftp/mail/fax/web/gnats.
newsadm:        news
newsadmin:      news
usenet:         news
ftpadm:         ftp
ftpadmin:       ftp
ftp-adm:        ftp
ftp-admin:      ftp
hostmaster:     root
mail:           postmaster
postman:        postmaster
post_office:    postmaster
# "abuse" is often used to fight against spam email
abuse:          postmaster
spam:           postmaster
faxadm:         root
faxmaster:      root
webmaster:      root
gnats-admin:    root
mailman:        root
mailman-owner:  mailman

# Majordomo can be used to have mailinglists on your site.
#majordomo:             "|/usr/lib/majordomo/wrapper majordomo"
#owner-majordomo:       root,
#majordomo-owner:       root,

# sample entry for a majordomo mailing-list called "test"
# read /usr/doc/packages/majordomo/README.linux for more information
# replace "test" with a new name and put the administrator into
# the "owner-test" alias instead of "root".
#
#test:                  "|/usr/lib/majordomo/wrapper resend -l test test-outgoin
g"
#test-outgoing:         :include:/var/lib/majordomo/lists/test
#test-request:          "|/usr/lib/majordomo/wrapper majordomo -l test"
#test-approval:         owner-test,
#owner-test-outgoing:   owner-test,
#owner-test-request:    owner-test,
#owner-test:            root,
#
# if you have bulk_mailer installed, you can replace the above
# "test-outgoing" line with the following:
#test-outgoing:         "|/usr/bin/bulk_mailer owner-test@host.com /var/lib/majo
rdomo/lists/test"
#
Some other questions...

Also, make sure that /brian/perlscript.pl is executable and that /usr/bin/perl is really where the Perl interpreter lives.

And as an aside, you don't need run.sh if you use
00,05,10,15,20,25,30,35,40,45,50,55 * * * * /usr/bin/perl /brian/perlscript.pl
Avatar of wxman1

ASKER

hi chris

yes it is executable, and yes that is where perl lives.

Is sendmail (or postfix, qmail, etc) running on this server? The aliases file doesn't redirect root's mail so it should be going into /var/spool/mail/root.
Avatar of wxman1

ASKER

jlevie

I don't think any of those are running.

I checked /var/spool/mail/root, and it is just those old messages I referred to earlier.

Is there something that needs to be enabled to allow cron's to run?
On any Linux/Unix system you need to have an MTA (sendmail, postfix, etc) running even if the system isn't a mail server. Things like cron need mail in order to report status & errors. You haven't said what Linux this is, but on a RedHat or similar you can do 'chkconfig sendmail on' followed by 'service sendmail start'.
Avatar of wxman1

ASKER

I'm using SuSe 9.1

II tried the chkconfig, but it didn't recognize sendmail
Avatar of wxman1

ASKER

jlevie,

I just ran another cron job:

0 * * * * echo "WAKE UP" 2>&1 /dev/console

just as a test, and the mail worked just fine.
Just a quick note : you can simplify the Cron line this way :

*/5 * * * * /brian/perlscript.pl

Now, a few ideas :

1. Are you sure of the path ? Usually home directories live in /home
2. Try */5 * * * * /brian/perlscript.pl 2>&1 /dev/console
3. Does your script rely on being launched from a specific directory or relies on specific environment variables ?
Avatar of wxman1

ASKER

Mac,

I created the brian directory in the root directory.

I tried suggestion 2, but still nothing happens.

I'm not sure I fully understand your 3rd question, but to run the script from say the root directoy I type /brian/perlscript and it runs perfectly.  I haven't set up any environment variables, or at least I don't think I have, as I don't really know what they are.
mmm... looks really weird. Permission problem maybe ?

You can check your env. variables by typing <i>set</i>, but it's quite unlikely to be the problem as well... If you don't get anything (after 5 minutes) with */5 * * * * /brian/perlscript.pl 2>&1 /dev/console, that means that the script doesn't output an error message...

Depending on your distribution, you should get CRON logs in /var/log/... (it's /var/log/syslog for me)
Avatar of wxman1

ASKER

Mac,

I wnet to  /var/log/ and did cat messages, and this is what I got:

Nov  4 13:06:53 rvt crontab[14235]: (root) LIST (root)
Nov  4 13:07:55 rvt crontab[14238]: (root) REPLACE (root)
Nov  4 13:07:59 rvt crontab[14239]: (root) LIST (root)
Nov  4 13:08:00 rvt cron[8169]: (root) RELOAD (tabs/root)
Nov  4 13:09:23 rvt crontab[14243]: (root) REPLACE (root)
Nov  4 13:10:00 rvt cron[8169]: (root) RELOAD (tabs/root)
Nov  4 13:13:28 rvt smbd[14287]: [2004/11/04 13:13:28, 0] lib/util_sock.c:get_peer_addr(978)
Nov  4 13:13:28 rvt smbd[14287]:   getpeername failed. Error was Transport endpoint is not connected
Nov  4 13:13:28 rvt smbd[14287]: [2004/11/04 13:13:28, 0] lib/util_sock.c:get_peer_addr(978)
Nov  4 13:13:28 rvt smbd[14287]:   getpeername failed. Error was Transport endpoint is not connected
Nov  4 13:13:28 rvt smbd[14287]: [2004/11/04 13:13:28, 0] lib/util_sock.c:write_socket_data(413)
Nov  4 13:13:28 rvt smbd[14287]:   write_socket_data: write failure. Error = Connection reset by peer
Nov  4 13:13:28 rvt smbd[14287]: [2004/11/04 13:13:28, 0] lib/util_sock.c:write_socket(438)
Nov  4 13:13:28 rvt smbd[14287]:   write_socket: Error writing 4 bytes to socket 7: ERRNO = Connection reset by peer
Nov  4 13:13:28 rvt smbd[14287]: [2004/11/04 13:13:28, 0] lib/util_sock.c:send_smb(630)
Nov  4 13:13:28 rvt smbd[14287]:   Error writing 4 bytes to client. -1. (Connection reset by peer)

Does that tell you anything, or am I looking at the wrong stuff.  I don't have a syslog folder.
You need at least a timeperiod with the minutes ending with 0, 5, 10, 15, ...

But it tells me :

root has done some operations
samba is probably misconfigured

Simplify the process and put a line before anything in your perl script:

#!/bin/perl
(or real path to your perl executable, might be /usr/bin/perl)

That should simplify by allowing you to only keep one script to do the job and might solve your problem.

Hope this helps.
Avatar of wxman1

ASKER

hi deurk,

 I already have #!/usr/local/bin/perl as the first line of my perl script, which is where the perl executable resides.
Just a question, what does your script do?
Avatar of wxman1

ASKER

it renames a file, then ftp's it to our webserver.
Can you post the script without any sensitive passwords or IP?
Avatar of wxman1

ASKER

#!/usr/bin/perl

use CGI;
use Net::FTP;
use File::Find;
use File::stat;

$format="jpg";
$HomeDir="/brian/";

chdir($HomeDir);

# Get list of files in  source directory.
if (opendir(DIR,".")) {
    @files=readdir(DIR);
    closedir(DIR);}

#Declaration of variables

    $CountVar=0;
    $FutureFile=6307200000;
    $oldestFile=" ";
    $currentTime=time();
    $testtime=0;


#This part will be house keeping locally, it should count the number
# of files in the directory and delete the oldest if more than 10 files exist.
#count files of type jpg, determine oldest one and newest one

    foreach $file(@files) {
        if($file=~/\d+\.$format/i){
            $CountVar=($CountVar+1);
            $comptime = (stat($file)->mtime);
            if($comptime<$FutureFile)
            {$oldestFile=$file;}

            if($comptime>$testime){
                $testtime=$comptime;
                $newestfile=$file;}

            $FutureFile=$comptime;
            }

    }

    if($CountVar>10){
        unlink($oldestFile);
    }

#This section will re-name the newest file into the proper format for the website

$oldname="$newestfile";

$year=substr($oldname,0,4);
$month=substr($oldname,4,2);
$date=substr($oldname,6,2);
$time=substr($oldname,8,4);

$newname="ir_".$year."_".$month."_".$date."_".$time.".jpg";
system("cp $newestfile $newname");

#This section will now begin to ftp the most recent file to the server

$LOGIC="xxx.xxx.xxx.xxx";
$file=$newname;
$dir="/maps/sat";

$ftp = Net::FTP->new($LOGIC,Passive => 1, debug =>1);
$ftp->login("username","password") or die 'login',$ftp-message;

$ftp->cwd($dir);
$ftp->binary();

$ftp->put($file) or die 'put',$ftp->message;
#$ftp->quit;

#This next section will perform housekeeping at the remote server
# by searching thru the files and finding the oldest one, then deleting it

@ftpfiles=$ftp-> ls($dir); #get list of files in remote directory

$RefTime=6307200000;
$rcount=0;

foreach $ftpfiles(@ftpfiles){
    $rcount=($rcount+1);
    $mdtm = $ftp->mdtm($ftpfiles) or die "Can't find $ftpfiles in $dir\n"; # get modification time of remote file
    $CalcTime=$mdtm;
    if($CalcTime<$RefTime){
      $roldestFile=$ftpfiles;}
    $RefTime=$CalcTime;
   
}

# if there are more than 10 images in remote directory, get rid of oldest

if($rcount>10){
    $ftp->delete($roldestFile);
}

$ftp->quit;

# The next section will delete the newly renamed file from the RVT computer

unlink($newname);



Try to put an echo into it at the begnining of the script to make sure it isn't executed by the cron job.
Also, what do you use to set the cron job? Command? Account?
Avatar of wxman1

ASKER

deurk,

I have to admit this is the first perl program I've ever written on my own, so could you please give an example of the echo, and where it should go?

Also, this is my first cron , and if I understand your question, I am logged on as root, root owns/executes the perl script, and as root, I made the cron by creating a txt file with the cron command called new.txt, then from the prompt I ran crontab new.txt.

That's a good thing to try to touch those new things, grats!

As for what I think, you could put a simple line:
print "SCRIPT STARTED";
before the line
use CGI;
just to make sure it displays something and then run it manually. You should see SCRIPT STARTED appear.

Now just wait 5 minutes and look at your /var/log/messages to check if you have anything coming out of it.

Hmmm also try to use the command
crontab -e
Does it work? You hsould be able to edit directly the cron scheduling tasks from there.

Also do a crontab -l and print out the result in here ;)
print "SCRIPT STARTED\n";

Will work much better.
That will just put an new line character but as the script doesn't output anything else imho, there is no need for it... anyway it will work with or without it so 'much better' might be a bit commercial ^^
Without the new line you might not get a mail message to let you know that the script ran.
I agree, you're right, the '/n' can avoid it.
Avatar of wxman1

ASKER

Ok,

I actually recieved a message in /var/mail/root:

From root@rvt.bas-serco  Fri Nov  5 17:00:06 2004
Return-Path: <root@rvt.bas-serco>
X-Original-To: root


Delivered-To: root@rvt.bas-serco
Received: by rvt.bas-serco (Postfix, from userid 0)
        id B4C404BC404; Fri,  5 Nov 2004 17:00:06 +0000 (GMT)
From: root@rvt.bas-serco (Cron Daemon)
To: root@rvt.bas-serco
Subject: Cron <root@rvt> /usr/bin/perl /brian/renamenew.pl
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
Message-Id: <20041105170006.B4C404BC404@rvt.bas-serco>
Date: Fri,  5 Nov 2004 17:00:06 +0000 (GMT)

SCRIPT STARTED

Also, the following was in /var/log/messages:
Nov  5 17:00:00 rvt CRON[23802]: (root) CMD (/usr/bin/perl /brian/renamenew.pl)

and lastly, running crontab -l produces:

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (new.txt installed on Fri Nov  5 16:51:24 2004)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
00,05,10,15,20,25,30,35,40,45,50,55 * * * * /usr/bin/perl /brian/renamenew.pl




ASKER CERTIFIED SOLUTION
Avatar of deurk
deurk

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of wxman1

ASKER

it worked it worked!

Thanks all for all of your help.  

Now on to my next PERL attempt, and next cron job.  Wish me luck.

Thanks again!
Good luck ^^