ellem has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a program. This is what I think it should do:

Open, clobber and write a file called PING.TXT
ping a site until it can't anymore then email me

Here's what I have so far:
#! /usr/bin/perl -w use strict ; use Mail::Sendmail; use diagnostics ; open (PING, '+> C:\PING\PING.TXT') or die "Can't create file; $!" ; # intentionally clobbering file my $pingstat = 0 ; my $ping = `ping -t 132.163.4.101` ; until ($pingstat) { $ping ; } else { $pingstat = 1 ; } my %mail = ( To => 'lmoran@wtsg.com', From => 'ellem@opt_online.net', Subject =>"The PING is dead!", Message =>"Go read your PING log" ); format PING = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $ping .
I have all manner of fancy plans after I get this working but the until loop seems to be wrong. I have compared it to the ones I have written before and to the explanation in the Camel (PP3 pp. 112-116) and I have noticed that I have no if statement but I don't know what I would put in an if statement anyway. (That makes me a pretty poor programmer doesn't it?) I say this becuase I want to say:

ping this until you can't, else change the value of the variable $pingstat to 1 and email me to go read my logs.
--
lmoran@wtsg.com
There's more than one way to do it, just don't use my way.

Replies are listed 'Best First'.
(shockme) Re: until Loop Question
by shockme (Chaplain) on Dec 14, 2001 at 02:14 UTC
    You'll probably do alot better using Net::Ping. It's whole purpose is to see whether a remote host is reachable.

    If things get any worse, I'll have to ask you to stop helping me.

Re: until Loop Question
by lestrrat (Deacon) on Dec 14, 2001 at 02:38 UTC

    How about this... ( untested, just something that came to mind )

    do{ ## note that some versions of ping keep pinging ## forever... you may need to use a flag like -c ## ( if available ) to limit the number of tries system( "ping your.ip.address" ); } while( $? != 0 );

    I like the Net::Ping idea by shockme as well, except it won't let you use icmp requests unless you make your script setuid, which although understandable, really really sucks

Re: until Loop Question
by chromatic (Archbishop) on Dec 14, 2001 at 05:00 UTC
    You need something in the until block that will change the state of the condition variable. They also don't usually take else blocks. Besides that, all your block is doing is returning whatever was captured from the external ping command. Worse yet, since the assignment to $ping is waiting on an external command, it'll wait until the ping stops.

    Net::Ping is the way to go.

      Clearly I am confused on the usage of the until loop. And while I have reworked the code to avoid the until loop entirely I would be interested to see how someone would correctly write:

      until something changes do this else do that

      or am I now hoplessly confused?
      --
      lmoran@wtsg.com
      There's more than one way to do it, just don't use my way.
        do{ ## do something that may or may not change $condition } until( $condition )

        ... this will execute the block after "do" until the expression after "until" evaluates to true. more examples....

        ## print "foo" until $count becomes 5 my $count = 0; do{ print "foo\n"; $count++; } until ( $count == 5 ); ## call some command until its exit status ## is 0 ( success ) do { system( "cmd" ); } until( $? == 0 );
Re: until Loop Question
by cfreak (Chaplain) on Dec 14, 2001 at 02:39 UTC

    Well it looks like your problem is using the ping in backticks. That's going to return whatever ping prints out to the shell, so even if you didn't have "ping" installed on your system, the shell would still put "ping:command not found" into your variable thus making it true.

    I'd look into shockme's suggestion of Net::Ping. Also a good way to notice things like this is to print your variables out to see if they are true or not.

    Chris

      um, no, because the original poster's code is a clear syntax error. you can't do until(){}else{}