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

Strange question, but when I run my little Solaris Ping -s output muncher, if I try to redirect stdout a la '> filename' the file doesn't get anything in it. The script runs fine to the screen. Here are the two command lines:

ping -s 192.168.1.1 | pinglog.pl

Works fine - output as expected...

ping -s 192.168.1.1 | pinglog.pl > pinglog.out

pinglog.out remains empty...what is going on??
Here is the script:
#!/usr/bin/perl -w use strict; my $newnum = 0; while (<>) { next if $_ =~ /data bytes/; my ($a, $b) = split (/:/, $_); chomp $b; my ($seq, $seqnum, $lat, $latsec) = split '=', $b; $seqnum =~ s/\s+//; $seqnum =~ s/.time//; # for debug... # print "seq: $seqnum\texpected: $newnum\n"; unless ($seqnum == $newnum ) { print "Ping failed at " . localtime(time - ($seqnum - $newnum) +) . "\t"; print "restored at " . localtime() . "\t"; print "Total Time (s) = " . ($seqnum - $newnum) . "\n"; } $newnum = $seqnum + 1; }
Any ideas?? Thanks ahead of time!

Replies are listed 'Best First'.
(z) Re: Redirect Question
by zigdon (Deacon) on Sep 15, 2003 at 16:44 UTC
    Like it was mentioned above, is it possible that your output is buffered? Try adding $| = 1 to the top of your script, see if that helps?

    -- zigdon

      Aha! The solution!

      Now, what did that do??? Was I not getting enough input into the buffer for the file write to happen; if so, how much is the buffer usually? Did the $| change the size of the buffer?
      Thanks for the quick fix!!
        AFAIK, the buffer size varies by platform, and by what's the destination. For STDOUT to the terminal, the buffer is usually around 256 bytes, I think. For files, it's probably several K, at least. All $| does it set the buffer to autoflush - see perlvar for details.

        -- zigdon

Re: Redirect Question
by phydeauxarff (Priest) on Sep 15, 2003 at 18:04 UTC
    On another note, why not go ahead and just add Net::Ping to your script so it will have the functionality instead of requiring you to pipe in output from ping?

    use Net::Ping; my $ping = new Net::Ping ("icmp"); my $PING_TIMEOUT = 2; my $IP=$_; if ($ping->ping($IP, $PING_TIMEOUT)) { print "Ping Succeeded \n"; } else { print "Ping failed\n";} $ping->close();

    Then you can just run your script with your IP as an argument...this would even make it easy to automate automate the script to run a list of IP's on a regular basis.

      Thanks all!
      The script is just a quick-and-dirty capture to quantify some outage times for a customer. Since I knew I could just grok the output from a ping -s on solaris, that is what I did - simple. Thanks for the ideas though, and I will use Net:Ping if I ever need to do this again.
      Cheers!
Re: Redirect Question
by nimdokk (Vicar) on Sep 15, 2003 at 16:25 UTC
    One thing, I think you will need to read from ARGV instead of $_.


    "Ex libris un peut de tout"
Re: Redirect Question
by kutsu (Priest) on Sep 15, 2003 at 16:32 UTC

    The  > pinglog.pl won't ever happen becuase it's waiting on ping to stop before it does, at least I think. You might try this, untested:

    ping -c 5 -s 192.168.1.1 | pinglog.pl > pinglog.out

    "Pain is weakness leaving the body, I find myself in pain everyday" -me

      On solaris, the -s for the ping command makes it send 1 packet every second, indefinetly. The point of this script is to catch holes in the sequence number and calculate timestamps for the lost pings, and log the timestamps to a file.

      I have even tried writing to an output file handle with my print statements to no avail. Works to the screen if I just use print, print FH doesn't. Ack :(