running a perl script with crontab


Page 1 of 2 12 LastLast
Results 1 to 15 of 27

Thread: running a perl script with crontab

  1. #1
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313

    running a perl script with crontab

    hey all,

    I'm very new to perl but managed to put together a script that reads my qmail logs, parses out the info I need and then writes records into a database table. I then have a php website that my users can go into and search for the status of an email.

    anywhoo.... the script works great except when I set it to run via crontab. It only half executes but I can't seem to find any error message telling me why. is there some kind of trick to getting a perl script to run via cron?

    thanks,
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  2. #2
    Join Date
    Sep 1999
    Posts
    3,202
    Errors and output from stuff run via cron are mailed to the user... got mail?

  3. #3
    Join Date
    Feb 2003
    Location
    New Jersey USA
    Posts
    62
    How are you adding the script to cron? Are you adding it to "your" crontab or to "root's" crontab? If its on root's crontab, have you run the script as the "root" user? I've seen a lot of people do this with scripts where they add it to the system's crontab which by default runs as root. Also by default most scripts that initiate from cron run as standard sh or bourne shell. Make sure that there is a shell directive on the first line of the script. You can also try writing a "wrapper shell script" calling the perl script from that.

    Hope this helps...

  4. #4
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313
    I wrote it as root, and added it to root's crontab. if I run it manually as root, it runs fine. via root's crontab however, no dice.

    the script starts out...

    #!/usr/bin/perl

    so that should work..

    It doesn't fail outright, it just won't write to the db, or read the log files to get the output to write into the DB, I can't tell which.
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  5. #5
    Join Date
    Feb 2003
    Location
    London
    Posts
    1,022
    Depends on where the perl script lives.
    The PATH for root usually doesn't include the current dir ie '.', so you'd prob have to specify the entire path eg /root/myperl.pl or wrap a shell script around it to do

    Code:
    cd /root
    ./myperl.pl
    You might want to ensure it opens a log file at the start and add a few print statements in order to check where it gets to etc.
    Cheers
    Chris

  6. #6
    Join Date
    Apr 2001
    Location
    SF Bay Area, CA
    Posts
    14,936
    Are you using environment variables in the script itself?

    Cron jobs usually don't run any shell startup files, so they usually don't get much in the way of environment variables...

  7. #7
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313
    I'm a little fuzzy on the whole environmental variables thing...

    perhaps it would help if I actually posted the script...

    Here's the script...

    Code:
    #!/usr/bin/perl
    
    print "I'm running now!!!\n";
    
    ## shut down firewall to allow db access: temporary fix
    
    system "/etc/init.d/iptables stop";
    
    ## get a list of all the qmail logfiles 
    
    system "/bin/ls /var/log/qmail/\@* > /var/log/qmail/new_filelist";
    system "/bin/ls /var/log/qmail/current >> /var/log/qmail/new_filelist";
    
    
    ## compare the new and old list, then write a file containing only the new filenames.
    system "/usr/bin/diff /var/log/qmail/old_filelist /var/log/qmail/new_filelist | grep \">\" > /tmp/newfiles";
    
    open FILES, "/tmp/newfiles";
    
    ## process all the lines in the list of new files.
    while(<FILES>) {
           chomp;
    
            my $logfileName = substr($_,2);
            print "logfile Name: $logfileName\n";
    
            open LOG, "/bin/cat $logfileName | tai64nlocal |";
    
            system "echo 'opened the file'";
    
            use DBI;
            my $dbh2 = DBI->connect( "dbi:mysql:MIS:192.168.1.5", "username", "password" ) or die "nope\n";
    
            #print "past the db connection\n";
    
    ## if the filename is "current" clear the database of all records from this filename, then re-create them with the newer "current" file.
            if($logfileName = "current") {
    
            my $delcurrent= "delete from MIS.qmail_log where FileName = 'current' && Server = 'Qmail1'";
            my $query = $dbh2->do( $delcurrent );
    
            }
            while(<LOG>) {
                    #chomp;
    
                    #print "inside the while\n";
    
                    # insert start of a new email into db
    
                    if(/info msg/) {
    
                            my $start_bytes = index($_,"bytes")+6;
                            my $end_bytes = index($_,"from") - ($start_bytes+1);
                            my $msgbytes = substr($_,$start_bytes,$end_bytes);
    
                            my $start_msgid = index($_,"info msg") + 8;
                            my $end_msgid = index($_,": bytes") - ($start_msgid+1);
                            my $msgID = substr($_,39,$end_msgid);
    
                            my $from_start = index($_,"<")+1;
                            my $from_end = index($_,">") - $from_start;
                            my $from = substr($_,$from_start,$from_end);
    
                            my $time = substr($_,0,19);
    
                            $msg_bytes[$msgID]=$msgbytes;
                            $from_add[$msgID]=$from;
    
                            my $new_query = "insert into MIS.qmail_log(id,type,log_time,msgID,size,from_add,stat,input_timestamp,FileName,Server)
                                            values ('null','new',unix_timestamp('$time'),'$msgID','$msgbytes','$from','new msg',
                                            unix_timestamp(now()),'$logfileName','Qmail1')";
    
                            #print "NEW: $new_query\n";
    
                            my $query = $dbh2->do( $new_query );
                    }
    
            ##############################################
            ###### insert new deliver info into db #######
            ##############################################
    
                    if(/starting delivery/) {
    
                            my $msgid_start = index($_,"msg")+4;
                            my $msgid_end = index($_,"to remote") - ($msgid_start+1);
    
                            my $delid_start = index($_,"delivery") + 9;
                            my $delid_end = index($_,": msg") - ($delid_start);
    
                            my $find_remote = index($_,"to remote");
                            my $find_local = index($_,"to local");
    
                            if($find_remote > 0) {
                                    $to_start = index($_,"to remote") + 10;
                            }
                            if($find_local > 0) {
                                    $to_start = index($_,"to local") + 9;
                            }
    
                            $msgID = substr($_,$msgid_start,$msgid_end);
                            $delID = substr($_,$delid_start,$delid_end);
                            my $to = substr($_,$to_start);
    
                            my $time = substr($_,0,19);
                            $del_msg[$delID]=$msgID;
    
                            $to_add[$msgID]=$to;
    
                            my $delto_query = "update MIS.qmail_log set to_add = '$to', delID = '$delID'
                                                    where msgID = '$msgID'
                                                    && size = '$msg_bytes[$msgID]'
                                                    && from_add = '$from_add[$msgID]'";
    
                            my $del_query = "insert into MIS.qmail_log(id,type,log_time,msgID,size,delID,from_add,to_add,stat,text,
                                            input_timestamp,FileName,Server)
                                            values ('null','startdel',unix_timestamp('$time'),'$msgID','$msg_bytes[$msgID]','$delID',
                                            '$from_add[$msgID]','$to','starting delivery','looking up and contacting recipients mailserver',
                                            unix_timestamp(now()),'$logfileName','Qmail1')";
    
                            #print "DELIVERY: $del_query\n";
    
                            my $query = $dbh2->do( $del_query );
    
                    }
    
            ##################################################
            ###### insert delivery attempt info into db ######
            ##################################################
    
                    if(/\d delivery/){
    
                            my $time = substr($_,0,19);
    
                            my $delid_start = index($_,"delivery") + 9;
                            my $delid_end = index($_,": ") - ($delid_start);
    
                            my $stat_start = index($_,": ")+2;
                            my $stat_end = index($_,": ",$stat_start) - $stat_start;
    
                            my $text_start = ($stat_start + $stat_end) + 2;
    
                            my $delID = substr($_,$delid_start,$delid_end);
                            my $stat = substr($_,$stat_start,$stat_end);
    
                            my $text = substr($_,$text_start);
    
                            $text =~ s/\"/ /g;
                            $text =~ s/\//-/g;
                            $str = $dbh2->quote($text);
                            #print "$str\n";
                            my $stat_query= "insert into MIS.qmail_log(id,type,log_time,msgID,delID,size,from_add,to_add,stat,text,
                                            input_timestamp,FileName,Server)
                                            values ('null','delstat',unix_timestamp('$time'),'$del_msg[$delID]','$delID','$msg_bytes[$del_msg[$delID]]',
                                            '$from_add[$del_msg[$delID]]','$to_add[$del_msg[$delID]]','$stat',\"$str\",
                                            unix_timestamp(now()),'$logfileName','Qmail1')";
    
                            #print "DELIVERY STATUS $stat_query\n";
                            my $query = $dbh2->do( $stat_query );
    
                    }
    
            }
            system "/bin/rm -f /root/logfile";
    }
    
    ## start up the firewall: temp solution
    
    system "/etc/init.d/iptables start";
    
    ## clean up the files and create a new "old_filelist" for next time.
    
    system "/bin/cp /var/log/qmail/old_filelist /var/log/qmail/old_filelist1";
    system "/bin/mv /var/log/qmail/new_filelist /tmp/old_filelist";
    system "cat /tmp/old_filelist | grep -v 'current' > /var/log/qmail/old_filelist";
    system "/bin/rm -f /tmp/newfiles";
    exit;
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  8. #8
    Join Date
    Jan 2001
    Location
    Somewhere in middle America
    Posts
    164
    Try running your script like this.

    env -i ./script.pl

    (maybe env - ./scriptl.pl on some systems)

    env -i will run the script with no environmental variables set.
    That should help you see if variables you need aren't set.

    I use DBI with informix databases and often run into problems because various env variables are required by the informix connection to be established.
    My Machine:
    Maytag SAV5905
    710 rpm Stainless Steel Drum
    Dual boot: Gentoo / Tide

  9. #9
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313
    tried the "env -i", it had no effect that I could see.

    I think I found the problem however...

    the line....

    if($logfileName = "current") {

    my $delcurrent= "delete from MIS.qmail_log where FileName = 'current' && Server = 'Qmail2'";
    my $query = $dbh2->do( $delcurrent );


    the single "=" should be a doubl "=" otherwise it sets the $logfileName to "current" instead of testing for it.

    Is this correct?

    thanks,
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  10. #10
    Join Date
    Apr 2001
    Location
    SF Bay Area, CA
    Posts
    14,936
    I have no idea, I can't read Perl... but I would guess that looking for a Perl tutorial (or reading one of the perlXXXXtut manpages, where XXXX turns into whatever part of Perl you want to learn about) might help.

    Certainly something as simple as whether = is assignment or comparison would turn up there.

  11. #11
    Join Date
    Oct 2002
    Location
    AZ, USA
    Posts
    110
    The '==' verses '=' is an easy miss in perl, and yes it could very well be the source of your problem as every time through the IF test returns TRUE and sets the Var to 'current'.

  12. #12
    Join Date
    Feb 2003
    Location
    London
    Posts
    1,022
    Actually,
    = is assignment ala 'C'
    == is numeric comparison
    eq is string comparison
    HTH
    Cheers
    Chris

  13. #13
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313
    eq is string comparison
    hmm, that would explain the error messages about numeric something or other....

    thanks!
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  14. #14
    Join Date
    Mar 2000
    Location
    NJ, USA
    Posts
    313
    still won't run via crontab...
    Jeff (aka Singlespeed)
    ~We have done so much for so long with so little, we are now qualified to do anything with nothing.

  15. #15
    Join Date
    Jul 2002
    Location
    Vladivostok, Russia
    Posts
    9,053
    Try running a shell script that executes your perl script instead of doing it directly from cron.
    "I was pulled over for speeding today. The officer said, "Don't you know
    the speed limit is 55 miles an hour?" And I said, "Yes, but I wasn't going
    to be out that long."

    How To Ask Questions The Smart Way
    COME VISIT ME IN RUSSIA NOW!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •