Bash - конвертировать сетевую маску в нотации CIDR?
Пример: у меня есть маска сети: 255.255.255.0
Есть ли в bash команда или простой скрипт для преобразования моей сетевой маски в нотацию /24?
4 ответа
Решение
Пример функции для Linux:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
ipcalc -p 1.1.1.1 $1 | sed -n 's/^PREFIX=\(.*\)/\/\1/p'
}
Результат:
$ IPprefix_by_netmask 255.255.255.0
/24
Та же функция без ipcalc, протестированная в Solaris и Linux:
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
bits=0
for octet in $(echo $1| sed 's/\./ /g'); do
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
let bits+=${#binbits}
done
echo "/${bits}"
}
Использование функции
subnetcalc
:IPprefix_by_netmask() { subnetcalc 1.1.1.1 "$1" -n | sed -n '/^Netw/{s#.*/ #/#p;q}' }
В чистом виде
bash
, преобразуйте IP в длинную восьмеричную строку и суммируйте ее биты:IPprefix_by_netmask () { c=0 x=0$( printf '%o' ${1//./ } ) while [ $x -gt 0 ]; do let c+=$((x%2)) 'x>>=1' done echo /$c ; }
Выход из IPprefix_by_netmask 255.255.255.0
(любая функция):
/24
Решение на основе awk
Хотя GNU awk не является Bash, он установлен по умолчанию в достаточном количестве дистрибутивов, поэтому это может быть полезно в смысле вопроса:
awk -F. '{
split($0, octets)
for (i in octets) {
mask += 8 - log(2**8 - octets[i])/log(2);
}
print "/" mask
}' <<< 255.255.255.240
Это печатает:
/28
Судя по ответу Саши, этот скрипт работает с dash
(протестировано с Ubuntu 18.04):
IPprefix_by_netmask() {
#function returns prefix for given netmask in arg1
bits=0
for octet in $(echo $1| sed 's/\./ /g'); do
binbits=$(echo "obase=2; ibase=10; ${octet}"| bc | sed 's/0//g')
bits=$(expr $bits + ${#binbits})
done
echo "/${bits}"
}