1

I just can't get the code below to work.

Code:

#!/bin/bash

ip=$1
first=$2
last=$3

if (( $first >= 1 && $first <= 255 && $last >= 1 && $last <= 255 && $first <= $last)); then

    range=0

else
    range=1
    fi

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0]$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]


    VIP=0
else
    VIP=1
    fi

if (( $range == 0 && $VIP == 0)); then

   echo "intiating ping scan for $1 $first-$last"
   echo ""
   echo "==================================================="
   for i in $(seq $first $last); do ping -c 1 ${ip[0]}.${ip[1]}.${ip[2]}.$i > /dev/null;done
       if [ $? -eq 0 ]; then
           echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is up"
       else
           echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is down"
           fi
else
    echo "invalid IP or range"
    echo "=================================================="
    echo "Usage: ./ping_scan.sh <ip[must end in 0]{ex. 192.168.5.0}> "
    echo "<start address {ex. 23}> <end address {ex. 254}>"
    fi

The issue revolves around this code snippet:

if (( $range == 0 && $VIP == 0)); then

echo "initiating ping scan for $1 $first-$last"
echo ""
echo "==================================================="
for i in $(seq $first $last); do ping -c 1 ${ip[0]}.${ip[1]}.${ip[2]}.$i > /dev/null;done
   if [ $? -eq 0 ]; then
       echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is up"
   else
       echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is down"
       fi
else
echo "invalid IP address or range"
echo "=================================================="
echo "Usage: ./ping_scan.sh <ip[must end in 0]{ex. 192.168.5.0}> "
echo "<start address {ex. 23}> <end address {ex. 254}>"
fi

I used set -x to confirm my suspicions. The issue I am having is I am only receiving output from the last IP address that is being pinged.

The for loop is running for each IP address, completing, getting $? for the last IP address pinged, and then the script is moving into the if statement and printing the status of the final IP address.

I need the for loop to run for each IP address and the if statement to run for each IP address and output the status of each. I know this can be done, and I have tried multiple configurations, but none seem to work.

How can I fix it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
H0rizonfire
  • 23
  • 1
  • 6
  • You have to move the `done`. The `if` is only hit after you've gone through your whole `for` loop. Proper indentation would help, too. – Benjamin W. Mar 06 '17 at 23:09
  • Thank you, another noob mistake. I appreciate the response. I think the indentation issue is coming when I am posting the code. Im still trying to figure out stack overflow's code blocks. – H0rizonfire Mar 06 '17 at 23:13
  • You can just copy-paste everything as-is from your editor, then select the whole code block and use Ctrl-K (or the `{}` button). – Benjamin W. Mar 06 '17 at 23:14
  • Awesome. I will do that from now on. I did go through and check indentations, and you were correct, there were some mistakes. – H0rizonfire Mar 06 '17 at 23:21
  • In the future, btw, please try to follow the guidelines at http://stackoverflow.com/help/mcve -- creating the smallest possible code sample tested to reproduce your problem. – Charles Duffy Mar 06 '17 at 23:37
  • (and as an aside -- `seq` is a nonstandard command, neither part of bash nor a standard POSIX-specified UNIX tool. Consider `for (( i=first; i – Charles Duffy Mar 06 '17 at 23:38
  • (...and as another aside -- http://shellcheck.net/ is your friend). – Charles Duffy Mar 06 '17 at 23:39
  • Thank you for the info and the asides Charles Duffy. shellcheck.net is going to be very useful! And thank you for the code snippet. That is going to come in handy. – H0rizonfire Mar 06 '17 at 23:44

1 Answers1

0

The if statement needs to be inside the loop.

for i in $(seq $first $last)
do 
    ping -c 1 ${ip[0]}.${ip[1]}.${ip[2]}.$i > /dev/null
    if [ $? -eq 0 ]; then
        echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is up"
    else
        echo "${ip[0]}.${ip[1]}.${ip[2]}.$i is down"
    fi
done
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • AH! thank you so much. Noob mistake number 2. I tried removing the done without thinking that of course it would be required. I have made the changes you have suggested and everything is working perfectly. Thank you so much! – H0rizonfire Mar 06 '17 at 23:14