if/els statement within perl script - newb

S

Stuart H

Since bash is horrible at date statements i had to convert my bash script
to perl....now i have a headache.. I had help to convert but now in
modifying i have messed it up..

i'm checking a returned value from a sql query and comparing it against
the date.
The two possible output types


[bluemoon@monitor]$ /usr/local/bin/sqsh -Uuser -Ppassword -S sql1 -h -i test.sql
[bluemoon@monitor]$
[bluemoon@monitor]$ /usr/local/bin/sqsh -Usql1_replicator -Pkaiisdead -S mtsql1 -h -i test.sql
0 2003110311:53:42/298


i am usure as to how to include a if $SQLOutput= null then exit, else...



#!/usr/bin/perl -w

use Date::Calc qw(Delta_DHMS);
use Date::Calc qw(Delta_Days);
use POSIX qw(strftime);
require Symbol;

$SENDMAIL_EXEC = '/usr/sbin/sendmail'; # Path to sendmail(8)
$BLUEMOON_RECV_EMAIL = '(e-mail address removed)';
my $bluemoon_sender = "bluemoon_monitor\@domain.com";

my @today = (strftime("%Y", localtime(time)),strftime("%m", localtime(time)), strftime("%d", localtime(time)),strftime("%H", localtime(time)),strftime("%M", localtime(time)),strftime("%S", localtime(time)));
my @timestamp;

my $day;
my $year;
my $month;
my $hour;
my $minutes;
my $seconds;
my $Dd;
my $Dh;
my $Dm;
my $Ds;

my $SQLOutput;
my $zero;

my $bluemoon_body;

$SQLOutput=`/usr/local/bin/sqsh -Uuser -Ppassword -S sql1 -h -i bluemoon.sql`;

if ($SQLOutput = null then exit; else < ------- not sure how to do this in
perl...

/(.)(.)(........)(....)(..)(..)(..)(.)(..)(.)(..)(....)/) { $zero = $2;
$year = $4; $month = $5; $day = $6; $hour = $7; $minutes = $9; $seconds = $11; }
@timestamp = ($year, $month, $day, $hour, $minutes, $seconds);
($Dd,$Dh,$Dm,$Ds) = Delta_DHMS(@timestamp,@today);

if (($Dd > 0 || $Dh > 0 || $Dm > 10) && $zero == 0 ) {
$bluemoon_body = join('',"Blue Moon Timestamp Check has
failed!\n\nThe UPLOADED Field = ",$zero,"\nThere has not been an update
in ", $Dd," days, ", $Dh," hours and ", $Dm," minutes.\n\nPlease restart
the interface or investigate\n\nBluemoon TimeStamp:
",@timestamp,"\nCurrent Timestamp: ",@today);

my $SEND_MAIL = Symbol->gensym;
open($SEND_MAIL, "|-") ||
exec($SENDMAIL_EXEC, '-i', '-t', "-f$bluemoon_sender");
print $SEND_MAIL <<"EOF";
Date: @today
From: $bluemoon_sender
To: $BLUEMOON_RECV_EMAIL
Subject: Blue Moon is Down!
$bluemoon_body
EOF
close($SEND_MAIL);

}

Thanks for any help
 
D

Darin McBride

Stuart said:
Since bash is horrible at date statements i had to convert my bash script

:) Horrible ... but doable.
to perl....now i have a headache.. I had help to convert but now in
modifying i have messed it up..

i'm checking a returned value from a sql query and comparing it against
the date.
The two possible output types


[bluemoon@monitor]$ /usr/local/bin/sqsh -Uuser -Ppassword -S sql1 -h -i test.sql
[bluemoon@monitor]$
[bluemoon@monitor]$ /usr/local/bin/sqsh -Usql1_replicator -Pkaiisdead -S mtsql1 -h -i test.sql
0 2003110311:53:42/298


i am usure as to how to include a if $SQLOutput= null then exit, else...


#!/usr/bin/perl -w

use Date::Calc qw(Delta_DHMS);
use Date::Calc qw(Delta_Days);

Both of these lines should be able to be combined:

use Date::Calc qw(Delta_DHMS Delta_Days);
use POSIX qw(strftime);
require Symbol;

You probably don't really want Symbol. You want IO::File.
$SENDMAIL_EXEC = '/usr/sbin/sendmail'; # Path to sendmail(8)

FYI - I recommend Net::SMTP or Mail::Sendmail. Further, you probably
don't want to use all caps for these variables.
$BLUEMOON_RECV_EMAIL = '(e-mail address removed)';
my $bluemoon_sender = "bluemoon_monitor\@domain.com";

my @today = (strftime("%Y", localtime(time)),strftime("%m",
localtime(time)), strftime("%d", localtime(time)),strftime("%H",
localtime(time)),strftime("%M", localtime(time)),strftime("%S",
localtime(time))); my @timestamp;

There has to be an easier way to get all those variables ;-) First,
you can get the output from localtime just once - can you imagine the
confusion if you ran this just as the date changed from one year to the
next? ;-)
my $day;
my $year;
my $month;
my $hour;
my $minutes;
my $seconds;
my $Dd;
my $Dh;
my $Dm;
my $Ds;

Too many variables.
my $SQLOutput;
my $zero;

my $bluemoon_body;

$SQLOutput=`/usr/local/bin/sqsh -Uuser -Ppassword -S sql1 -h -i
bluemoon.sql`;

if ($SQLOutput = null then exit; else < ------- not sure how to do this in
perl...

exit unless $SQLOutput;
/(.)(.)(........)(....)(..)(..)(..)(.)(..)(.)(..)(....)/) { $zero = $2;
$year = $4; $month = $5; $day = $6; $hour = $7; $minutes = $9; $seconds =
$11; } @timestamp = ($year, $month, $day, $hour, $minutes, $seconds);
($Dd,$Dh,$Dm,$Ds) = Delta_DHMS(@timestamp,@today);

Put this on multiple lines. Further, you may want to use unpack for
this rather than a regular expression.
if (($Dd > 0 || $Dh > 0 || $Dm > 10) && $zero == 0 ) {
$bluemoon_body = join('',"Blue Moon Timestamp Check has
failed!\n\nThe UPLOADED Field = ",$zero,"\nThere has not been an update
in ", $Dd," days, ", $Dh," hours and ", $Dm," minutes.\n\nPlease restart
the interface or investigate\n\nBluemoon TimeStamp:
",@timestamp,"\nCurrent Timestamp: ",@today);

Again, use whitespace. It's your friend. And ours (those who you're
asking to look at the code).
my $SEND_MAIL = Symbol->gensym;
open($SEND_MAIL, "|-") ||
exec($SENDMAIL_EXEC, '-i', '-t', "-f$bluemoon_sender");

Using IO::pipe may be better here.

my $SEND_MAIL = IO::pipe->new();
$SEND_MAIL->reader($SENDMAIL_EXEC, '-i, '-t', "-f$bluemoon_sender");
$SEND_MAIL->writer();

print $SEND_MAIL <<"EOF";
....
EOF

Of course, using Mail::Sendmail takes care of all of this, much more
nicely, too, I think.
 
B

Brian McCauley

Darin McBride said:
You probably don't really want Symbol. You want IO::File.

You probably don't even want IO::File.

If you have Perl 5.6 (or is that 5.6.1?) you can omit the explicit
initialisation - file handles autovivify.
Using IO::pipe may be better here.

my $SEND_MAIL = IO::pipe->new();
$SEND_MAIL->reader($SENDMAIL_EXEC, '-i, '-t', "-f$bluemoon_sender");
$SEND_MAIL->writer();

If you have Perl 5.8 (I think) then you can avoid the clunklyness of
the old open/exec solution and also avoid the clunklyness of IO::pipe
by using the LIST form of open().

open( my $SEND_MAIL, '|-',
$SENDMAIL_EXEC, '-i', '-t', "-f$bluemoon_sender") or die $!

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
B

Ben Morrow

[All this code is untested. If there are any foolish errors I
apologise :)]

Stuart H said:
#!/usr/bin/perl -w

Good, however you missed

use strict;
use Date::Calc qw(Delta_DHMS);
use Date::Calc qw(Delta_Days);

You shouldn't use a module more than once.
use Date::Calc qw/Delta_DHMS Delta_Days/;
use POSIX qw(strftime);
require Symbol;

Why require rather than use?
You don't actually need this at all: see below.
$SENDMAIL_EXEC = '/usr/sbin/sendmail'; # Path to sendmail(8)
$BLUEMOON_RECV_EMAIL = '(e-mail address removed)';

As you're now using strict, you'll need to make these 'my' variables.
A better alternative would be to use Mail::Sendmail.

Perl programmers tend to reserve ALL_CAPS for filehandles and magic
variables like $AUTOLOAD.
my $bluemoon_sender = "bluemoon_monitor\@domain.com";
my @today = (strftime("%Y", localtime(time)),strftime("%m",
localtime(time)), strftime("%d", localtime(time)),strftime("%H",
localtime(time)),strftime("%M", localtime(time)),strftime("%S",
localtime(time)));

Eeeugh. Try

my @now = localtime time;
my @today = map { strftime $_, @now } qw/%Y %m %d %H %M %S/;

, or see below for a different way of doing it altogether.
my @timestamp;

my $day;
my $year;
my $month;
my $hour;
my $minutes;
my $seconds;
my $Dd;
my $Dh;
my $Dm;
my $Ds;

my $SQLOutput;
my $zero;

my $bluemoon_body;

Perl Is Not C: it's usually clearer to declare your variables right
down where you first use them.
$SQLOutput =
`/usr/local/bin/sqsh -Uuser -Ppassword -S sql1 -h -i bluemoon.sql`;

I have a superstitious dislike of `` and would always use qx//
instead, but that's purely personal preference.
if ($SQLOutput = null then exit; else < ------- not sure how to do this in
perl...

exit unless $SQLOutput;
/(.)(.)(........)(....)(..)(..)(..)(.)(..)(.)(..)(....)/) { $zero =
$2; $year = $4; $month = $5; $day = $6; $hour = $7; $minutes = $9;
$seconds = $11; } @timestamp = ($year, $month, $day, $hour,
$minutes, $seconds);
($Dd,$Dh,$Dm,$Ds) = Delta_DHMS(@timestamp,@today);

Perl Is Not Awk: there's no need for the (/.../) {...}
construct. Also, m// will match against $_ unless you tell it
otherwise.

I would have done something more like

use Date::parse qw/str2time/; # at the top with the others

my $now_re = strftime "^ 0 \s+ %Y %m %d %H %M", @now;

unless ($SQLOutput =~ /$now_re/x) {

$SQLOutput =~ # convert to an ISO8601 date
s/^ (\d+)\s+ (\d{4})(\d{2})(\d{2})(\d{2})(\d{2}) .*/$2-$3-$4T$5:$6/x
or die "can't parse date '$SQLOutput'";
my $SQLstatus = $1;

my $SQLtime = str2time $SQLOutput;
(my $diff = time - $SQLtime) > 0
or die "SQL returned future date: $SQLOutput";

my ($Dd, $Dh, $Dm) =
map { strftime $_, gmtime $diff } qw/%j %H %M/;
$Dd =~ s/^0*//;

my $today = strftime "%FT%R", localtime time;
# or "%Y-%m-%dT%H:%M" if your strftime doesn't do %F & %R

my $bluemoon_body = <<MAIL;
Blue Moon Timestamp Check has failed!

The UPLOADED Field = $SQLstatus.
There has not been an update in $Dd days, $Dh hours and $Dm minutes.

Please restart the interface or investigate.

Bluemoon TimeStamp: $SQLoutput
Current Timestamp : $today
MAIL

This doesn't produce the timestamps in exactly the same format as
before, but the modification is trivial. I am assuming you wish to
ignore seconds, and that the last update will always be less then a
year in the past.
if (($Dd > 0 || $Dh > 0 || $Dm > 10) && $zero == 0 ) {
$bluemoon_body = join('',"Blue Moon Timestamp Check has
failed!\n\nThe UPLOADED Field = ",$zero,"\nThere has not been an update
in ", $Dd," days, ", $Dh," hours and ", $Dm," minutes.\n\nPlease restart
the interface or investigate\n\nBluemoon TimeStamp:
",@timestamp,"\nCurrent Timestamp: ",@today);

my $SEND_MAIL = Symbol->gensym;

You don't need to do this any more. Just use
open my $SEND_MAIL, "|-", $SENDMAIL_EXEC, "-i", "-t", "-f$bluemoon_sender"
or die "Can't fork sendmail: $!";

Or, better, use Mail::Sendmail.
open($SEND_MAIL, "|-") ||
exec($SENDMAIL_EXEC, '-i', '-t', "-f$bluemoon_sender");
print $SEND_MAIL <<"EOF";
Date: @today

This is hardly the RFC822 format for datestamps! Leave it out and let
Sendmail add one.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top