Bash 实现子网掩码与前缀长度互转

前缀长度转换为子网掩码

脚本: prefix_to_mask.sh

#!/bin/bash
# date: 2018-03-03
# license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
# author: nanpuyue <[email protected]> https://blog.nanpuyue.com

num=$((4294967296 - 2**(32-$1)))
for i in {3..0};do
    echo -n $((num / 256**i))
    num=$((num % 256**i))
    (($i == 0)) && echo || echo -n .
done

这段脚本完全使用 Bash 内置函数实现,不调用外部进程。

子网掩码转换为前缀长度

脚本: mask_to_prefix.sh

#!/bin/bash
# date: 2018-09-15
# license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
# author: nanpuyue <[email protected]> https://blog.nanpuyue.com

n=0;b=3
for i in ${1//./ };do
    if ((0 <= i < 256));then
        let n+=$((2**(b*8) * i))
        let b--
    else
        exit 1
    fi
done
[[ $(echo "obase=2;$n"|bc) =~ ^(1+)0*$ ]] &&\
((${#BASH_REMATCH[0]} == 32)) &&\
echo ${#BASH_REMATCH[1]}

本来也想用纯 Bash 实现,但为了脚本的简洁还是调用了 bc 命令,当给出的子网掩码有误时,输出结果为空同时脚本返回值为 1 。

Gist:

  1. 将前缀长度转换为子网掩码
  2. 将子网掩码转换为前缀长度

标签: Linux, Bash, Shell, 网络

已有 4 条评论

  1. leaeasy leaeasy

    看着好疼,乔老师玩python吧
    netmask = "255.255.255.0"
    sum([bin(int(x)).count("1") for x in netmask.split(".")])

  2. jiyan jiyan

    有个叫做 ipcalc 的软件很适合最这个事情~

添加新评论