使用布尔表达式Bash脚本

时间:2016-02-09 12:30:38

标签: bash boolean

我正在尝试编写一个Bash脚本来计算两个地址的最小公共子网。

理论:我必须将IP从十进制更改为二进制,然后在两个IP上应用XNOR。

我试着写这个:

#!/bin/bash
echo "Ebter the first ip"
read ip1
echo "Enter the second ip"
read ip2  

#Separate octs of first ip  

a1=`echo $ip1 | awk 'BEGIN{FS="."}{print $1}'`
a2=`echo $ip1 | awk 'BEGIN{FS="."}{print $2}'`
a3=`echo $ip1 | awk 'BEGIN{FS="."}{print $3}'`
a4=`echo $ip1 | awk 'BEGIN{FS="."}{print $4}'`  
#convert decimal to binary

b1=`echo "obase=2;$a1" | bc`
b2=`echo "obase=2;$a2" | bc`
b3=`echo "obase=2;$a3" | bc`
b4=`echo "obase=2;$a4" | bc`  

#Separate octs of second ip

c1=`echo $ip2 | awk 'BEGIN{FS="."}{print $1}'`
c2=`echo $ip2 | awk 'BEGIN{FS="."}{print $2}'`
c3=`echo $ip2 | awk 'BEGIN{FS="."}{print $3}'`
c4=`echo $ip2 | awk 'BEGIN{FS="."}{print $4}'`  

#convert decimal to binary (second IP)

d1=`echo "obase=2;$c1" | bc`
d2=`echo "obase=2;$c2" | bc`
d3=`echo "obase=2;$c3" | bc`
d4=`echo "obase=2;$c4" | bc`

e1=`echo $b1 || $d1 | rev`
e2=`echo $b2 || $d2 | rev`
e3=`echo $b3 || $d3 | rev`
e4=`echo $b4 || $d4 | rev`

echo "$e1.$e2.$e3.$e4"    

我有两个问题:

  1. 我需要将XNOR应用于二进制IP(逐位),但如果特定位的结果变为零,我想停止操作并使另一位跟随零,零也。 / p>

  2. 我需要XNOR忽略“。”。

  3. 有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

首先,使用read将地址拆分为整数部分要简单得多。

IFS=. read a1 a2 a3 a4 <<< "$ip1"
IFS=. read b1 b2 b3 b4 <<< "$ip2"

完成后,您可以在每个部分使用shell算法;不需要先将每个显式转换为二进制文件。

但是,在bash中计算掩码仍然有点棘手。试试这个:

set_mask_part () {
    local m=255
    local a=$1
    local b=$2

    # While a and b are different, shift m left
    # and shift and b right. When a and b are equal,
    # the mask converges to the correct value.
    while (( a != b )); do
        (( m = (m << 1) & 255 ))
        (( a = a >> 1 ))
        (( b = b >> 1 ))
    done
    echo "$m"
}


# Get the left-most mask byte first, and repeat for
# each byte to the right as long as the previous byte is 255
m1=$(set_mask_part "$a1" "$b1")
(( m1 == 255 )) && m2=$(set_mask_part "$a2" "$b2") || m2=0
(( m2 == 255 )) && m3=$(set_mask_part "$a3" "$b3") || m3=0
(( m3 == 255 )) && m4=$(set_mask_part "$a4" "$b4") || m4=0

mask="$m1.$m2.$m3.$m4"