7

I'm trying to create some simple pass/fail test scripts, but I am having some challenges as outlined below. My intent is to get the full results of a command (such as ping) into a results.txt file to keep, but also parse the results.txt file for different checks to raise if issues are detected:

#!/bin/bash
ping -c 20 google.com > results.txt
packetloss = `awk '/packet loss/{x=$6} END{print x}' results.txt`
echo "$packetloss" >> debug.txt
#  if packetloss > 0, add to an error.txt to fail
#  if avg ping time > 5ms, add to an error.txt to fail

The packetloss variable is not getting the awk information from the results.txt file (sending to a debug file to review). I was wondering if there is something about shell scripting that would prevent this and an associated workaround?

Manually running awk on results.txt returns '0%' which is the expected result.

11

Spaces are not allowed around =!

So:

#!/bin/bash
ping -c 20 google.com > results.txt
packetloss=$(awk '/packet loss/{print $6}' results.txt)
echo "$packetloss" >> debug.txt

Or even shorter:

ping -c 20 google.com |
    awk '/packet loss/{sub(/%/, "");print $6 >> "debug.txt"}'

NOTE:

  • There is no need to assign the x variable; you can print $6 directly.
  • AWK itself can create new files with its output
  • The backquote
    `
    is used in the old-style command substitution, for example :
foo=`command`

The foo=$(command) syntax is recommended instead. Backslash handling inside $() is less surprising, and $() is easier to nest.

Check http://mywiki.wooledge.org/BashFAQ/082

Extra solution using Perl:

ping -c 20 google.com |
    perl -lne '/(\d+)%\s+packet\s+loss/ and print $1' >> debug.txt
  • 1
    bingo - that must be the number one problem with compiled language programmers trying to write scripts :-P – dhartford Dec 30 '14 at 21:51
  • just for extra, is there a way to use awk to never show '%' or similar characters? – dhartford Dec 30 '14 at 22:02
  • Yes, POST edited accordingly, check sub() – Gilles Quenot Dec 30 '14 at 22:05
1
#!/usr/bin/perl
my $host=shift or die("Usage $0 host\n");

open(PING , "-|", "ping -c 20 $host") or die;
open(DEBUG, ">>", "debug.txt"       ) or die; 

while(<PING>){
  if(m!(\d+)% packet loss!     ){ $Lost=$1 }
  if(m!rtt.*= (.+?)/(.+?)/(.+)!){ $Avg=$2  }
}

if   ( $Lost > 0 ) { print DEBUG "not ok: lost pcks ($Lost%)\n"    }
elsif( $Avg  > 5 ) { print DEBUG "not ok: too slow  ($Avg)\n"      }
else               { print DEBUG "ok: ping\n"                      }
  • Global file-handles should be avoided. Instead use : open my $debug, ">>", "debug.txt" or die $!; – Gilles Quenot Dec 31 '14 at 0:19
  • @sputnick: thank you. You are right or course. I was just trying to make it look simpler... (always a dangerous choice) :) – JJoao Dec 31 '14 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.