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. Advertisements

  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. Advertisements

  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. Advertisements

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. David K. Worman

    Perl newb in need of help with script.

    David K. Worman, Sep 18, 2003, in forum: Perl
    Replies:
    2
    Views:
    519
    David K. Worman
    Sep 18, 2003
  2. dpackwood
    Replies:
    3
    Views:
    2,188
  3. Guest

    ELS-Script Report tools

    Guest, Jun 7, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    512
    Guest
    Jun 7, 2005
  4. Guest

    ELS-SCRIPT Report Tools

    Guest, Jun 7, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    510
    Guest
    Jun 7, 2005
  5. luca72

    unify els database

    luca72, Jul 2, 2007, in forum: Python
    Replies:
    4
    Views:
    365
    luca72
    Jul 9, 2007
  6. Chaddy2222
    Replies:
    7
    Views:
    601
    Chaddy2222
    Oct 25, 2008
  7. jay
    Replies:
    7
    Views:
    445
    Chad Perrin
    May 3, 2007
  8. Replies:
    4
    Views:
    502
    ccc31807
    Jul 29, 2011
Loading...