IP地址计算器脚本

时间:2016-01-28 15:33:49

标签: bash

我需要编写一个Bash脚本,将IP地址从CIDR格式转换为四元格式。

我必须按以下格式输入IP地址:

10.10.10.10/24

如果我以这种方式输入它:

10.10.10.10 255.255.255.0  

应出现错误信息。

我试过这个剧本:

#!/bin/bash
echo "enter you ip"
read ip
case $ip in
*.*.*.*/*)
b=`echo $ip | cut -d/ -f1`
a=`echo $ip | cut -d/ -f2`

if [ $a -eq 24 ];then
   echo "$b 255.255.255.0"
elif [ $a -eq 25 ];then
   echo "$b 255.255.255.128"
elif [ $a -eq 26 ];then
   echo "$b 255.255.255.192"
elif [ $a -eq 27 ];then
   echo "$b 255.255.255.224"
elif [ $a -eq 28 ];then
   echo "$b 255.255.255.240"
elif [ $a -eq 29 ];then
   echo "$b 255.255.255.248"
elif [ $a -eq 30 ];then
   echo "$b 255.255.255.252"
elif [ $a -eq 31 ];then
   echo "$b 255.255.255.254"
elif [ $a -eq 32 ];then
   echo "$b 255.255.255.255"
fi


case $ip in
 *.*.*.* *.*.*.*)
echo "enter a valid address"

esac

但是我收到了错误

  

./ ipcalculater2.sh:第32行:意外标记“附近的语法错误。'

     

./ ipcalculater2.sh:第32行:` )&# 39;

我的剧本出了什么问题?

2 个答案:

答案 0 :(得分:1)

以下是bash中可能从CIDR转换为网络掩码表示法的四种方式示例。

#!/usr/bin/env bash

if [[ "$1" != *.*.*.*/* ]]; then
  echo "Usage: ${0##*/} ip.ad.dr.ess/bits" >&2
  exit 1
fi

# separate our input into network and mask using IFS
IFS=/ read network bits <<<"$1"

# build a temporary variable $s that we'll use to build $bitmask
# for the first three variants...
read zeros <<< $(printf '%032s' 0)
s=${zeros//0/1}${zeros}

# convert the mask into a 32-digit binary number
bitmask=${s:$((32-bits)):32}

# Four different methods for generating the netmask...

# The first two use `bc` and `dc`. One is likely installed on your system.
read mask1 <<<$( dc -e "2i $(fold -w8 <<<"$bitmask " | paste -sdp -)" | paste -sd. - )
read mask2 <<<$( fold -w8 <<<"$bitmask" | paste - | bc -e 'ibase=2' | paste -sd. - )

# And if dc and bc are unavailable, or you prefer not to spawn subshells, or
# risk missed dependencies, you can do this in pure bash with a few more lines.
unset mask3
for ((i=0;i<4;i++)); do
  mask3+="${mask3:+.}$((2#${bitmask:$((8*i)):8}))"
done

# And finally, instead of a loop, you can do the same thing with fancy math:
# This variant avoides the need for $bitmask, set above.
mask4="$(( 2**32 - (1 << (32-$bits)) ))"
mask4=$(( mask4/2**24 )).$(( mask4/2**16 %256 )).$(( mask4/2**8 % 256 )).$(( mask4 % 256 ))

# Print the results, obviously.
echo "network=$network"
echo "netlength=$bits"
echo "netmask via 'dc': $mask1"
echo "netmask via 'bc': $mask2"
echo "netmask via loop: $mask3"
echo "netmask via math: $mask4"

我已经包含了适用于dcbc各个代码的代码,因为我无法预测您的系统上哪个计算器可用。这些计算器用于基本转换。如果您不介意将脚本更长一些,则可以使用生成fold的方法避免生成外部工具(如paste$netmask3以及计算器)。 / p>

请注意,在第三种情况下,bc的这种用法取决于* BSD中存在的-e选项的可用性。如果您正在使用GNU bc(即您在Linux中使用),请使用其他变体。

您当然可以调整输出以满足您的需求,并修剪您不使用的脚本部分。

答案 1 :(得分:0)

请检查此更正:

#!/bin/bash
echo "enter you ip"
read ip
case $ip in
*.*.*.*/*)
b=`echo $ip | cut -d/ -f1`
a=`echo $ip | cut -d/ -f2`

if [ $a -eq 24 ];then
   echo "$b 255.255.255.0"
elif [ $a -eq 25 ];then
   echo "$b 255.255.255.128"
elif [ $a -eq 26 ];then
   echo "$b 255.255.255.192"
elif [ $a -eq 27 ];then
   echo "$b 255.255.255.224"
elif [ $a -eq 28 ];then
   echo "$b 255.255.255.240"
elif [ $a -eq 29 ];then
   echo "$b 255.255.255.248"
elif [ $a -eq 30 ];then
   echo "$b 255.255.255.252"
elif [ $a -eq 31 ];then
   echo "$b 255.255.255.254"
elif [ $a -eq 32 ];then
   echo "$b 255.255.255.255"
fi
;;

 *.*.*.*\ *.*.*.*)
echo "enter a valid address"
;;

esac