-
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.
-
Errors and output from stuff run via cron are mailed to the user... got mail?
-
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...
-
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.
-
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
-
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...
-
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.
-
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
-
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.
-
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.
-
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'.
-
Actually,
= is assignment ala 'C'
== is numeric comparison
eq is string comparison
HTH
Cheers
Chris
-
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.
-
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.
-
Try running a shell script that executes your perl script instead of doing it directly from cron.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|