我需要编写一个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;
我的剧本出了什么问题?
答案 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"
我已经包含了适用于dc
和bc
各个代码的代码,因为我无法预测您的系统上哪个计算器可用。这些计算器用于基本转换。如果您不介意将脚本更长一些,则可以使用生成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