示例: 我有这个网络掩码:255.255.255.0
在bash中,是否有一个命令或一个简单的脚本可以用符号转换我的网络掩码 /24?
subnetcalc
的功能:
IPprefix_by_netmask() {
subnetcalc 1.1.1.1 "$1" -n | sed -n '/^Netw/{s#.*/ #/#p;q}'
}
在纯
bash
中(即没有像sed
或bc
这样的外部实用程序),将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
RHEL6/RHEL7 的示例功能:
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
在其他 Linux 发行版中,ipcalc 选项可能有所不同。
无需 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}"
}
虽然 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
根据 Sasha 的回答,该脚本适用于
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}"
}
可以通过bash原生完成
#!/bin/bash
mask2cidr(){
ONES=$(eval eval echo "'\$((('{"${1//./,}"}'>>'{7..0}')%2))'")
eval echo '$(('"${ONES// /+}"'))'
}
mask2cidr "$1"
$ ./mask2cidr.sh 255.192.0.0
10
顺便说一句,反向函数
cidr2mask(){
OCTETS=$(eval echo '$(((1<<32)-1<<32-$1>>'{3..0}'*8&255))')
echo "${OCTETS// /.}"
}
$ ./cidr2mask.sh 10
255.192.0.0