Bash Hacking

There are times in a network engineer’s life when you’re handed a massive list of hostnames or IPs and asked to make sense of them. You can make short work of these if you have access to a bash shell. Or you can be the donkey doing the donkey work and do it by hand.

If you have a a list of hostnames you want to check resolve to valid IP addresses then you could use something like this:

#!/bin/sh
{
for HOST in `cat inputfile.hosts`; #contains a list of newline delimted hostnames. These are read one line at a time
do
  (echo "Got $HOST"); #echos the hostname currently being read
  LOOKUP_RESULT=$(nslookup $HOST | grep Address: | tail -1); #does a grep for the "Address" field returned by a successful lookup and then tails the last line. Reads this into a variable called LOOKUP_RESULT
  LOOKUP_FAIL=$(echo $LOOKUP_RESULT | grep "#" | wc -l); #handles the failure condition for the lookup. If a lookup fails the result of the nslookup's last line will include a "#" which is the lookup server's port. This is read into a variable called LOOKUP_FAIL
  if [ $LOOKUP_FAIL -eq 1 ] #evaluates if the failure condition is true. If a single line is returned by the wc function, then the result is true.
  then
      (echo "bad input for $HOST"); #echos the host that doesn't resolve to an IP address.
  else
      (echo "Lookup result $LOOKUP_RESULT"); #echos the IP address for a successful lookup
  fi
done
} > lookup.out #outputs anything echoed in the code block above to a file called lookup.out

Admittedly, the above is a dirty hack. Especially for the failure condition, but it works well enough for me. I’ve not got enough time to clean up, but I may have to dust it off at some point.

The other case is when you’re given a huge number of IP addresses which then need to be mapped to hostnames or FQDNs.

Here’s one I adapted from one I found on the internet.

#!/bin/sh
{
for IP in `cat filename.hosts`
do
     printf "$IP\t";
        LOOKUP_RES=`nslookup $IP`;
        FAIL_COUNT=`echo $LOOKUP_RES | grep "** server can't find " | wc -l`;
        if [ $FAIL_COUNT -eq 1 ]
        then
             NAME='Bad FQDNS\n';
        else
             NAME=`echo $LOOKUP_RES | grep -v nameserver | cut -f 2 | grep name | cut -f 2 -d "=" | sed 's/ //'`;
        fi
        echo $NAME;
done;
} > filename.out

This reads in a number of newline delimited IP addresses from a file, does an nslookup on them and assigns the result to a variable LOOKUP_RES. A grep is performed on LOOKUP_RES and read into a variable FAIL_COUNT which is used to evaluate the result of the lookup. Text is echoed depending on the value of FAIL_COUNT. Results are output to filename.out.

This too requires cleanup. It does not cover all the failure conditions, but handled enough of them to allow the exceptions to be performed manually.

A few things to keep in mind:

  • When using = to assign variables, you cannot use spaces before and/or after the = sign.
  • Use () to enclose commands.
  • $() can be used to assign the result of a command to a variable
Possible improvements:
  • Modify the script to take input/output filenames as arguments.
  • Cover nslookup cases where it babbles on about authoritative lookups.
  • Cover cases where the input filename contains blank lines.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s