Solved

CRON job to run perl script

Posted on 2004-11-02
794 Views
Last Modified: 2013-12-16
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

0
Question by:wxman1
    35 Comments
     
    LVL 40

    Expert Comment

    by: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?
    0
     

    Author Comment

    by:wxman1
    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.
    0
     
    LVL 40

    Expert Comment

    by:jlevie
    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'?
    0
     

    Author Comment

    by:wxman1
    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.
    0
     
    LVL 40

    Expert Comment

    by:jlevie
    Check the aliases file and see if mail to root has been aliased to someone (either /etc/aliases or /etc/mail/aliases).
    0
     

    Author Comment

    by:wxman1
    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"
    #
    0
     
    LVL 14

    Expert Comment

    by:chris_calabrese
    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
    0
     

    Author Comment

    by:wxman1
    hi chris

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

    0
     
    LVL 40

    Expert Comment

    by:jlevie
    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.
    0
     

    Author Comment

    by:wxman1
    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?
    0
     
    LVL 40

    Expert Comment

    by:jlevie
    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'.
    0
     

    Author Comment

    by:wxman1
    I'm using SuSe 9.1

    II tried the chkconfig, but it didn't recognize sendmail
    0
     

    Author Comment

    by:wxman1
    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.
    0
     
    LVL 3

    Expert Comment

    by:mac_
    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 ?
    0
     

    Author Comment

    by:wxman1
    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.
    0
     
    LVL 3

    Expert Comment

    by:mac_
    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)
    0
     

    Author Comment

    by:wxman1
    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.
    0
     
    LVL 3

    Expert Comment

    by:mac_
    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

    0
     
    LVL 2

    Expert Comment

    by:deurk
    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.
    0
     

    Author Comment

    by:wxman1
    hi deurk,

     I already have #!/usr/local/bin/perl as the first line of my perl script, which is where the perl executable resides.
    0
     
    LVL 2

    Expert Comment

    by:deurk
    Just a question, what does your script do?
    0
     

    Author Comment

    by:wxman1
    it renames a file, then ftp's it to our webserver.
    0
     
    LVL 2

    Expert Comment

    by:deurk
    Can you post the script without any sensitive passwords or IP?
    0
     

    Author Comment

    by:wxman1
    #!/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);



    0
     
    LVL 2

    Expert Comment

    by:deurk
    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?
    0
     

    Author Comment

    by:wxman1
    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.

    0
     
    LVL 2

    Expert Comment

    by:deurk
    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 ;)
    0
     
    LVL 40

    Expert Comment

    by:jlevie
    print "SCRIPT STARTED\n";

    Will work much better.
    0
     
    LVL 2

    Expert Comment

    by:deurk
    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 ^^
    0
     
    LVL 40

    Expert Comment

    by:jlevie
    Without the new line you might not get a mail message to let you know that the script ran.
    0
     
    LVL 2

    Expert Comment

    by:deurk
    I agree, you're right, the '/n' can avoid it.
    0
     

    Author Comment

    by:wxman1
    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




    0
     
    LVL 2

    Accepted Solution

    by:
    So did it work?
    Looks like the job is correctly executed ^^
    0
     

    Author Comment

    by:wxman1
    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!
    0
     
    LVL 2

    Expert Comment

    by:deurk
    Good luck ^^
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    With the help of BASH shell and IF command it is possible to find out if file exists or not. Generally, this is known as conditional expressions. Conditional expressions are used by the [][] compound command and the test and [] builtin commands to t…
    This is the error message I got (CODE) Error caused by incompatible libmp3lame 3.98-2 with ffmpeg I've googled this error message and found out sometimes it attaches this note "can be treated with downgrade libmp3lame to version 3.97 or 3.98" …
    Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
    Connecting to an Amazon Linux EC2 Instance from Windows Using PuTTY.

    856 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now