if/els statement within perl script - newb

Discussion in 'Perl Misc' started by Stuart H, Nov 3, 2003.

  1. Stuart H

    Stuart H Guest

    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 = '';
    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
    Stuart H, Nov 3, 2003
    #1
    1. Advertising

  2. Stuart H wrote:

    > 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 = '';
    > 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.

    > 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
    Darin McBride, Nov 3, 2003
    #2
    1. Advertising

  3. Darin McBride <> writes:

    > Stuart H wrote:
    >
    > > require Symbol;

    >
    > You probably don't really want Symbol. You want IO::File.


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

    > > my $SEND_MAIL = Symbol->gensym;


    If you have Perl 5.6 (or is that 5.6.1?) you can omit the explicit
    initialisation - file handles autovivify.

    > > 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();


    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\\
    Brian McCauley, Nov 3, 2003
    #3
  4. Stuart H

    Ben Morrow Guest

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

    "Stuart H" <post@to_group.com> wrote:
    > #!/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 = '';


    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

    --
    . | .
    \ / The clueometer is reading zero.
    . .
    __ <-----@ __
    Ben Morrow, Nov 3, 2003
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest

    ELS-Script Report tools

    Guest, Jun 7, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    400
    Guest
    Jun 7, 2005
  2. Guest

    ELS-SCRIPT Report Tools

    Guest, Jun 7, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    401
    Guest
    Jun 7, 2005
  3. luca72

    unify els database

    luca72, Jul 2, 2007, in forum: Python
    Replies:
    4
    Views:
    289
    luca72
    Jul 9, 2007
  4. Chaddy2222
    Replies:
    7
    Views:
    476
    Chaddy2222
    Oct 25, 2008
  5. Replies:
    4
    Views:
    287
    ccc31807
    Jul 29, 2011
Loading...

Share This Page