If this is in the wrong forum, I apologize. It deals with perl programming, but the behavior change exists, as noted, between a manual shell run and a cron-driven run; if that means this belongs in another forum, I respectfully request that my question be moved where it belongs.
Everything below is running on SuSE machines; either 9.3 or 11.3. I've had the same behavior on each.
I'm trying to set up an email system to warn me when something fails on the servers I'm requested to maintain. I've got a perl script that I had to write some time back that can email files for me, so I scavenged from it for this purpose.
I'm writing all of the error streams into a directory '/home/log_mail/' on each server. A copy of my script is supposed to run hourly, and send any output .txt files in that directory to me, then rename them so they won't be sent a second time. (Renaming from '$name'.txt to '$name'.txt.old)
This works. However, since I'm getting output files from stderr on the projects I'm mapping to this, I'm getting a number of blank files in this directory. In order to keep the script(s) from spamming me, I'd thought to toss in a filesize marker to determine whether or not a file actually had something in it; if the size is zero, the script will not mail the file.
I know about the '-s' option; I'm trying to use that in my code for the size-based filter I wanted. When I've run the script manually, I've gotten the test files in that directory that I knew should go. However, while running as a scheduled task (called from cron.hourly or in the crontab file), I'm not getting anything.
I created a dummy project that did the same split, only without any of the email-calling routines. I'm getting the same output results from it as from the original: it works properly on manual run, but not on cron-driven run.
Below is the code of my dummy script:
Code:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Net::SMTP;
use MIME::Lite;
my $count;
my $p1;
my $datadir = "/home/log_mail/";
my $filesz;
opendir DH, "$datadir" or die " could not read listing: $!";
while ($_ = readdir(DH))
{
if (m/.txt/g)
{
$p1=pos $_;
$count++;
print "\n$count" . ') ';
print $_, " " x (30-length($_));
print "\n";
my $filesz = -s "$_";
if (0 == $filesz)
{
print "File $_ had zero file size.\n";
}
else
{
print "File $_ had file size $filesz\n";
}
}
}
Also,the contents of the directory I'm working with:
Code:
total 16
drwxrwxrwx 2 root root 208 Dec 9 15:30 .
drwxr-xr-x 14 root root 440 Dec 9 15:15 ..
-rwxr-xr-x 1 root root 615 Dec 9 15:13 email-Dummy
-rw-r--r-- 1 root root 773 Dec 9 15:31 email-log.err
-rw-r--r-- 1 root root 145 Dec 9 15:31 email-log.log
-rw-r--r-- 1 root root 0 Dec 9 14:36 kumquat.txt
-rw-r--r-- 1 root root 47 Dec 9 14:58 rutabega.txt
When I run this manually, I get the following results:
Code:
1) rutabega.txt
File rutabega.txt had file size 47
2) kumquat.txt
File kumquat.txt had zero file size.
When I let the crontab run it, with output to the .log file on stdout and the .err file on stderr, I get the following:
Code:
Log File:
1) rutabega.txt
File rutabega.txt had zero file size.
2) kumquat.txt
File kumquat.txt had zero file size.
Err File:
Use of uninitialized value in numeric eq (==) at /home/log_mail/email-Dummy
line 26 (#1)
(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.
To help you figure out what was undefined, perl tells you what operation
you used the undefined value in. Note, however, that perl optimizes your
program and the operation displayed in the warning may not necessarily
appear literally in your program. For example, "that $foo" is
usually optimized into "that " . $foo, and the warning will refer to
the concatenation (.) operator, even though there is no . in your
program.
With that information, it seems fairly clear that the program is blowing up on the size comparison for rutabega.txt; it's treating it as undefined on a cron run. (It may be doing the same for kumquat.txt as well; I can't tell based on this.) I don't understand why it would behave that way, though, given that it works when running the script manually. What am I missing here that's causing the difference?