【问题标题】:Bash - Convert netmask in CIDR notation?Bash - 以 CIDR 表示法转换网络掩码?
【发布时间】:2018-10-29 00:41:01
【问题描述】:

示例: 我有这个网络掩码:255.255.255.0

在 bash 中,是否有一个命令或一个简单的脚本可以将我的网络掩码转换为符号 /24?

【问题讨论】:

  • 简单的 Python 脚本(因此不作为答案发布):import ipaddress,math;print("/" + str(32-math.ceil(math.log2(int(ipaddress.IPv4Address(input()))^2**32-1))))

标签: bash cidr netmask


【解决方案1】:
  1. 函数使用subnetcalc:

    IPprefix_by_netmask() {
        subnetcalc 1.1.1.1 "$1" -n  | sed -n '/^Netw/{s#.*/ #/#p;q}'
    }
    
  2. 在纯 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

【讨论】:

    【解决方案2】:

    基于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
    

    【讨论】:

      【解决方案3】:

      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}"
      }
      

      【讨论】:

      • 该函数的ipcalc 版本在我的系统上不输出任何内容,(Lubuntu v17.10)。运行 ipcalc -p 1.1.1.1 255.255.255.0 会返回 "Unknown option: -p" 错误。 ipcalc 版本是 0.41-5.
      • 这工作:ipcalc -n 1.1.1.1 $1 | sed -n '/^Netm/{s#.*= #/#;s/ .*//p;q}'
      • ipcalc -nb 1.1.1.1 "$1" | sed -n '/Netmask/s/^.*=[ ]/\//p
      【解决方案4】:

      根据 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}"
      }
      

      【讨论】:

        猜你喜欢
        • 2021-06-02
        • 2021-05-14
        • 2016-05-06
        • 1970-01-01
        • 2016-08-25
        • 2020-12-22
        • 2014-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多