2013-03-06 8 views
1

Мне нужно рассчитать подсеть, имея IP-адрес и маску сети в оболочке машины Solaris (bash, но может быть и другим).Рассчитать подсеть в оболочке Solaris

Некоторые примеры:

IP=192.168.100.6, MASK=255.255.255.0 => SUBNET=192.168.100.0 
IP=11.95.189.33, MASK=255.255.0.0 => SUBNET=11.95.0.0 
IP=66.25.144.216, MASK=255.255.255.192 => SUBNET=66.25.144.192 

У меня есть два способа вычислить это:

SUBNET=$((`echo $IP | awk 'BEGIN { FS = "." } ; {print $1}'`&`echo $MASK | awk 'BEGIN { FS = "." } ; {print $1}'`)).\ 
$((`echo $IP | awk 'BEGIN { FS = "." } ; {print $2}'`&`echo $MASK | awk 'BEGIN { FS = "." } ; {print $2}'`)).\ 
$((`echo $IP | awk 'BEGIN { FS = "." } ; {print $3}'`&`echo $MASK | awk 'BEGIN { FS = "." } ; {print $3}'`)).\ 
$((`echo $IP | awk 'BEGIN { FS = "." } ; {print $4}'`&`echo $MASK | awk 'BEGIN { FS = "." } ; {print $4}'`)) 

и

l="${IP%.*}";r="${IP#*.}";n="${MASK%.*}";m="${MASK#*.}" 
subnet=$((${IP%%.*}&${NM%%.*})).$((${r%%.*}&${m%%.*})).$((${l##*.}&${n##*.})).$((${IP##*.}&${NM##*.})) 

Но я думаю, что оба из них немного "грязный". Мне нужен «более чистый» способ подсчета подсети, который легко понять другим людям в моем проекте.

Я предпочитаю не использовать Perl или питона, но можно было бы рассмотреть.

ответ

1

Предположим, что вы храните IP и маску на две оболочки переменных: $ip и $mask:

awk -vip="$ip" -vmask="$mask" 'BEGIN{ 
split(ip,a, "."); 
split(mask,b,"."); 
for(i=1;i<=4;i++)a[i]=b[i]==255?a[i]:b[i]; 
printf"SUBNET=";for(i=1;i<=3;i++)printf a[i]".";printf a[4]}' 

даст вам результат в формате: SUBNET=xxx.xxx.xxx.xxx

один пример:

kent$ ip="192.168.100.6"                                     

kent$ mask="255.255.255.192"                                    

kent$ awk -vip="$ip" -vmask="$mask" 'BEGIN{split(ip,a, "."); split(mask,b,".");for(i=1;i<=4;i++)a[i]=b[i]==255?a[i]:b[i]; printf"SUBNET=";for(i=1;i<=3;i++)printf a[i]".";printf a[4]}' 
SUBNET=192.168.100.192 
+0

это работает только тогда, когда ф находится в первой подсети в основной сети. Например. он не работает для ip = "10.0.0.99" vmask = "255.255.255.196" – Kveri

+0

@Kveri, какого результата вы ожидаете? – Kent

+0

Извините, я имел в виду vip = "10.0.0.99" и vmask = "255.255.255.192". Результат, полученный вашим кодом, - SUBNET = 10.0.0.192. Правильный результат: 10.0.0.64 – Kveri

1

Мое решение делает то, что на самом деле необходимо сделать. Ip и маска «и» вместе. Это то, что я использовал.

Предполагая, что здесь $ ip и $ mask определены переменные оболочки.

awk -vip="$ip" -vmask="$mask" 'BEGIN{ 
    sub("addr:","",ip); 
    sub("Mask:","",mask); 
    split(ip,a,"."); 
    split(mask,b,"."); 
    for(i=1;i<=4;i++) 
    s[i]=and(a[i],b[i]); 
    subnet=s[1]"."s[2]"."s[3]"."s[4]; 
    print subnet; 
}' 

сжат:

awk -vip="$ip" -vmask="$mask" 'BEGIN{sub("addr:","",ip);sub("Mask:","",mask);split(ip,a,".");split(mask,b,".");for(i=1;i<=4;i++)s[i]=and(a[i],b[i]);subnet=s[1]"."s[2]"."s[3]"."s[4];print subnet;}' 

работает аналогично примеру, приведенному Кентом.

Пример:

[rahul]$ ip=172.16.232.159 
[rahul]$ mask=255.255.254.0 
[rahul]$ awk -vip="$ip" -vmask="$mask" 'BEGIN{sub("addr:","",ip);sub("Mask:","",mask);split(ip,a,".");split(mask,b,".");for(i=1;i<=4;i++)s[i]=and(a[i],b[i]);subnet=s[1]"."s[2]"."s[3]"."s[4];print subnet;}' 
172.16.232.0 
+0

Мне нравится этот, но похоже, что вы используете [gawk] (https://www.gnu.org/software/gawk/manual/html_node/Bitwise-Functions.html) У меня есть функция «3 раза ошибка» и никогда определены» – gildux