Previous

Next


36. Another Perl Example Explained

open(FILE, "/usr/sbin/traceroute -n $ARGV[0] 2>/dev/null|");
        
  • Open the traceroute command to get its output. Notice that the IP will have to be passed into the script, and that the standard error has been piped to /dev/null (because traceroute outputs its first line {that I didn't want displayed} to STDOUT).
      while (<FILE>) {
        $data = $_;
            
  • While traceroute still producing output, put each line (one line at a time for this example!) into $data.
        if ($data =~ m/^\s?\d+\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([0-9.]* ms|
    \*)\s+([0-9.]* ms|\*)\s+([0-9.]* ms|\*)/) {
            
  • Here's our big regex! We are trying to match:
    • The start of the line
    • Followed by an optional space
    • Followed by one or more digits (this is the hop number). By default traceroute only does 30 hops, so \d{1,2} would have been just as good here, but because there is always a space after the hop number, it doesn't really matter.
    • Followed by one of more spaces
    • Followed by a series of 4 sets of 1 to 3 digits, separated by literal dots. This is the IP address of the hop. Notice we used traceroute -n to ensure that the IP form would be used! Notice also the IP address is grouped with brackets so we can use it later.
    • Followed by one or more spaces
    • Followed by zero or more of the characters 0-9 and literal dot, then a space, then the literal "ms" (for the time of the hop in milliseconds, OR a literal star when there was no response or a timeout on the hop. Note: Yes, there's options left out here! What if we got a "!H" back? Or a time in something other than milliseconds? It all comes down to what you are doing - in the case I wrote this for, these were very unlikely to occur, so I didn't bother to worry about these options (not that to do so would be very hard). It all comes down to what you know about your data, and matching what you want vs. what you don't.
    • Followed by one or more spaces, and the above again, etc.
  • Then we assign $1, $2, $3 and $4 to variables (so we can channge them - backreference variables are not editable in Perl).
          $a =~ s/ ms//;
          $b =~ s/ ms//;
          $c =~ s/ ms//;
            
  • We have to trim the " ms" from the times so that we can add them together - so here we see the use of a regex to do a search and replace. Perl does this using "s/regex/replace/". In this case, we search for the " ms" and replace it with nothing!
  • And we finish up with some adding, averaging and displaying - all pretty normal Perl stuff.

  • Previous

    Next

    Andrew Hill

    For LinuxSA Meeting, 21 November 2000