how to sum ip addresses - bash

I'm creating a *.deb package that transform your wireless card into an hotspot.
I'm stuck at the configurations:
I have to write a postinst file in which I ask to the user what ip address he likes for his hotspot and then use it to generate the range & the subnet addresses for the isc-dhcp-server.
Something like that:
10.10.0.01 + 0.0.0.9 = 10.10.0.10
I know how to assign strings and numbers to variables and how to ask to user his choosen IP, but how to modify a variable and assign the result to another one? expr thinks it's a floating number and won't work.
Hoping that everything it's clear enough,
waiting for a help,
thank you in advance

Avoid leading zeros.
IFS="." read -a a <<< 10.10.0.1
IFS="." read -a b <<< 0.0.0.9
s="$[a[0]+b[0]].$[a[1]+b[1]].$[a[2]+b[2]].$[a[3]+b[3]]"
echo $s
Output:
10.10.0.10

Ok, I found a workaround method:
when I ask to the user its choosen ip I use these:
IFS="." read -r a b c d
choosenip="$a.$b.$c.$d"
subnetip="$a.$b.$c.0"
rangeipmin="$a.$b.$c.20"
rangeipmax="$a.$b.$c.30"
IFS change the default "space" or "tab" to whatever you want.
So when I have to put these in the dhcpd.conf with "echo", I just have to call the variables.
If you have more elegant ways to do that, you're welcome.
Thank you

Related

Dynamic variable names based on value

Probably a noob question, but I'm having a particular challenge where I want to dynamically generate variable names based on a value. Eg. If I'd require 3 variables, variable names to be incremented dynamically var_0,var_1,var_3 respectively.
The solution I have right now is barebones. I'm just using read -p get user input and save it to variable. So for 5 hosts, I've just duplicated this 5 times to get the job done, but not a clean solution. I was looking around and reading through declare and eval but haven't got anywhere
Thinking of a solution where I input no. of hosts first and this dynamically picks up and asks for user input based on number of hosts and saves to variables incremented dynamically
Any help is appreciated, cheers
Use arrays. However, you don't have to ask the user for the number of hosts. Let them enter as many hosts as they like and finish by entering an empty line:
echo "Please enter hosts, one per line."
echo "Press enter on an empty line to finish."
hosts=()
while read -p "host ${#hosts[#]}: " host && [ -n "$host" ]; do
hosts+=("$host")
done
echo "Finished"
Alternatively, let the user enter all hosts on the same line separated by whitespace:
read -p "Please enter hosts, separated by whitespace: " -a hosts
To access the individual hosts use ${hosts[0]}, ${hosts[1]}, ..., ${hosts[${#hosts[#]}]}.
To list them all at once use ${hosts[#]}.
Use an array instead!
But read can actualy create dynamic vars, just like this:
for i in {1..3}; do
read -p 'helo: ' var_$i
done

On microblaze uclinux: put IP address to variable

Yes, this is related to Putting IP Address into bash variable. Is there a better way but nothing of the ideas there work for me on the microblaze uclinux.
I wish to have my ip address of eth0 stored to a shell variable that I can write a script using it. I need alternative ideas how to do this.
ifconfig is available if that helps.
I found that in the file /etc/config/dhcp0.conf the correct ip address is stored, here's the file's content:
1 192.168.10.102
How can I remove the 1 and space without using following commands
grep
sed
cut
this also does not work: echo ${variable:2}
You can use the shell's read built-in:
read num ip </etc/config/dhcp0.conf
$num will contain the number at the beginning of the line, $ip will contain the IP.
Assign ifconfig output of eth0 to array
ifout=($(ifconfig eth0))
Strip off everything before the semicolon of the 6th element of array and assign it to the variable $ethip
ethip=${ifout[6]#*:}

Translate numbers (IP address) inside a variable (bash)

My problem is that I'm having an IP address like 10.3.1.33
This IP address is inside a variable ip=10.3.1.33
Now I want to translate the 33 inside that IP address with a "*".
The "33" can change, so that this number has to be automatically put somewhere in a variable or so.....
I have no clue how to do that. Thanks for any advice :)
In your very specific case you could use:
$ ip="10.3.1.33"
$ printf "%s\n" "${ip/33/*}"
10.3.1.*
And to replace (remove) everything after the last period:
$ ip="10.3.1.33"
$ printf "%s\n" "${ip%.*}.*"
10.3.1.33
The later is POSIX compatible while the first is available in bash (among other shells)
I can think about this:
ip=1.2.3.4
ip1=${ip%.*}.*

Using multiple values for single variable in a loop

I have a small loop problem as below.
I have 3 different values to be used while running the same script -
va1="some-value1"
va2="some-value2"
va3="some-value3"
Now I want to use these three variable values to be used for running the same command, like -
while (i=0,i<=3,i++)
do
bin/java -s (run something with $var);
done
Now I want $var taking the value of var1, var2 and var3 each time it runs,
so can someone please tell me how do we achieve the above?
I tried doing -
for $1 $2 $3
do
case 1
case 2
case 3
done
OR
while read a b c
do
<code assumed to have loop iteration>
done <<< $(command)
But it isnt working as expected... Would really appreciate your help on this.
Thanks,
Brian
You forgot the 'in' part of the syntax:
for var in $va1 $va2 $va3
do
command $var
done
try
while ((i=0,i<=3,i++))
do
eval bin/java -s \$var$i
done
This is a great example of how to use eval. Note that 1. the value of $i is seen by the shell has it scans the line. Then because $var is escaped like \$var, it is not
'make visible' in the first scan. 2. Eval forces a 2nd scan of the cmd-line, so it sees $var1 or whatever, and that value is substituted into the command-line for execution.
I hope this helps.
P.S. Welcome to StackOverflow and let me remind you of three things we usually do here: 1) As you receive help, try to give it too, answering questions in your area of expertise 2) Read the FAQs, http://tinyurl.com/2vycnvr , 3) When you see good Q&A, vote them up by using the gray triangles, http://i.imgur.com/kygEP.png , as the credibility of the system is based on the reputation that users gain by sharing their knowledge. Also remember to accept the answer that better solves your problem, if any, by pressing the checkmark sign , http://i.imgur.com/uqJeW.png
You can use indirect variable expansion with ${!...}:
va1="some-value1"
va2="some-value2"
va3="some-value3"
for ((i=1;i<=3;i++)); do
varname="va$i"
echo "$varname = ${!varname}"
done
This prints:
va1 = some-value1
va2 = some-value2
va3 = some-value3

to which subnet IP address belongs?

I have to write a script in bash , perl or python.
I got file with three columns (for manually manage connect-proxy)
SUBNET/IP socks_port socks_ip
1.2.3.* 1080 9.8.7.6
1.1.* 1080 6.8.7.6
I want to know to which subnet belongs IP address,
for example:
$ my_script 1.1.1.2
this IP belongs to 1.1.* subnet so I want back second line.
BASH: quick and dirty, use cut, then grep over the file.
PYTHON: use ip.rsplit() and then line.split()[].startswith() iterating through the file.
PERL: no idea.
Cheers!
If the file is in the format given (i.e. using *), it'll be fairly easy to use bash pattern matching to compare this to the ip address. However, as #Mark Drago pointed out, this format anything except octet-boundary subnets, so if you need to support arbitrary subnet boundaries, you need a better format.
Assuming you are using the "1.2.*" format, this should work:
#!/bin/bash
ip="$1"
found_match=false
while read subnet socks_port socks_ip; do
if [[ "$ip" == $subnet ]]; then # this'll do glob-style pattern matching against $subnet
echo "subnet=$subnet, socks_port=$socks_port, socks_ip=$socks_port"
found_match=true
break # assuming you don't want to check for multiple matches
fi
done </path/to/subnet/file
if ! $found_match; then
echo "No match found in subnet file"
fi

Resources