LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Shell script to increment IP variables into ranges using /29 /28 /26 etc? (https://www.linuxquestions.org/questions/linux-newbie-8/shell-script-to-increment-ip-variables-into-ranges-using-29-28-26-etc-877667/)

joecam1673 04-28-2011 12:45 PM

Shell script to increment IP variables into ranges using /29 /28 /26 etc?
 
So, I've been a member of this forum for a while and, as the header pointed out when I logged in today, I've never actually asked a questions. Usually I just scrape through the forums and google until I find someone who has already asked the question I have and piece together my own answers but I can't seem to make that happen this time so here goes...

I am trying to write a shell script that I thought would be relatively simple but isn't really coming together.

What I need is a script that adds an IP in what I assume would be to variables based on the "read -e" input and then a third variable thats the subnet shorthand (/29 or whatever also from read -e). Once thats in I'd like to use what I assume would be a while loop to not only increment the last octet of the IP but also run the command to add that IP to a vps the number of usable IP's in the subnet. So increment the last octet 5 times and run the command 5 times so I can just add a first IP and give its range. Doable? Any help or suggestions or even just pointing me toward a pertinent tut/tuts would be much appreciated.

Thanks for readin'
joe

16pide 04-28-2011 02:38 PM

could you maybe give us something easier to read.
For example you might give us how the script would run:
Code:

Input your network address: 192.168.10.0/24
Here are the possible addresses:
192.168.10.1
192.168.10.2
192.168.10.3
etc ...

and if that's the script you want, then maybe this URL is useful: http://www.ipaddresslocation.org/ip-address-ranges.php

grail 04-28-2011 09:54 PM

As per previous post, if you supply examples of your inputs and outputs it makes it much easier to assist.

The idea sounds fairly trivial (based on current information), so here is a link to help with learning scripting.

joecam1673 05-01-2011 09:55 AM

Basically I'm looking for this on a superficial level;

Please enter the name of the container to add IPs:ctxxxx
Please enter the first usable IP in the range:192.168.10.50
Please enter the subnet:/29

Then it would use the vzctl set ctxxxx --ipadd 192.168.10.50 --save (5 times, incrementing that last octet each time.)

Thanks for responding. I'll read over your links. They are much appreciated.

joe

joecam1673 08-18-2011 05:42 PM

Here's what I came up with. Seems pretty dirty so if anyone has any best practice tips or whatever to help clean it up I'd welcome them gladly. Virtuozzo doesn't have a shell command to add IP ranges to VPS's so if anyone else uses it, here ya go. :)

joe

Code:

#!/bin/bash

echo -n "Please enter container name(ie ctxxxxx): "
read CT
echo -n "Please enter first IP in range: "
read IP
echo -n "Please enter subnet(ie /29): "
read SUBNET

OCT1=$(echo $IP | cut -d "." -f1)
OCT2=$(echo $IP | cut -d "." -f2)
OCT3=$(echo $IP | cut -d "." -f3)
OCT4=$(echo $IP | cut -d "." -f4)

if [ "$SUBNET" == "/29" ]
        then
                END=$(($OCT4 + 4))
        for IPFULL in `seq $OCT4 $END`
        do
                vzctl set $CT --ipadd $OCT1.$OCT2.$OCT3.$IPFULL --save
        done
elif [ "$SUBNET" == "/28" ]
        then
                END=$(($OCT4 + 12))
        for IPFULL in `seq $OCT4 $END`
        do
                vzctl set $CT --ipadd $OCT1.$OCT2.$OCT3.$IPFULL --save
        done
fi


grail 08-21-2011 06:57 AM

Initial suggestions are as follows:

1. You do not seem to check any of the user input

2. Are you never allowing more than 2 subnets? If we assume more, you can remove the ifs altogether:
Code:

(( END = OCT4 + ( 2 ** (32 - ${SUBNET#/} ))))
for (( IPFULL = OCT4; IPFULL <= END; IPFULL++ ))

3. The above leads me to question how you were calculating the END??

4. An alternative to your echo and cut routine:
Code:

set - ${IP//./ }
The above allows you to now refer to each segment using the positional parameter numbers, ie OCT1 = $1 (This of course assumes that IP has been checked and is a correct address format)

5. You can also use bash builtin substitution:
Code:

vzctl set $CT --ipadd ${IP%$4}$IPFULL --save
This assumes previous step has been provided

Hope some of this helps.

joecam1673 02-16-2013 07:43 PM

I know it's been ages since I originally posted this but I did find your response very helpfull. Thanks for the advise.

dariusrickard 02-16-2013 11:41 PM

great
 
nice thread. thanks for sharing that information. it was very informative.

David the H. 02-17-2013 03:40 PM

Here's a simpler way to chop up the address string:

Code:

$ address=192.168.10.0/24

$ IFS='./' read -ra ipnums <<<"$address"

$ printf '%s\n' "${ipnums[@]}"
192
168
10
0
24

Now you have an array with five numbers in it. You could alternately supply five named variables, of course, for portability or better clarity.

string manipulations in bash

joecam1673 02-17-2013 06:11 PM

Good point. If you're going to change the field separator, this would be simpler still.
Code:

IFS='.'
IP=($1)
echo "${IP[@]}"


grail 02-18-2013 01:29 AM

Actually, whilst simpler you have missed the subnet option at the end which is after '/' hence your last array element would be something like:
Code:

echo ${IP[3]]
0/24


joecam1673 02-19-2013 05:15 AM

ohh, touche

David the H. 02-24-2013 03:41 PM

I would still maintain that using read is the cleaner option, since you don't have to modify IFS globally. It's generally a good idea to avoid doing that, since it usually means you also have to remember to change it back afterwards, and forgetting to do so can lead to unpleasant and difficult to diagnose side-effects.

It's also probably slightly faster, as only a single command is executed. Finally, as I mentioned, you can replace the array with individual variables, if it suits the script flow better.

Code:

IFS='./' read -r oct1 oct2 oct3 oct4 subnet <<<"$address"


All times are GMT -5. The time now is 05:02 PM.