使用 bc 比较两个 IP 地址

使用 bc 比较两个 IP 地址

我正在尝试使用 bc 命令比较两个 IP 地址,但是数值较低的 IP 不会被捕获在测试中。

这是我的代码:

TEST=$(echo "$i < $IP_BRD && $i > $IP_LOW " | bc -q )

如果TEST结果为 1,则该过程继续,否则退出。

检查下面的例子:

++ echo '191.35 < 187.254 && 191.35 > 184.1 '
+ TEST=0
++ echo '191.35 < 191.254 && 191.35 > 188.1 '
++ bc -q
+ TEST2=0
++ echo '191.35 < 195.254 && 191.35 > 192.1 '
++ bc -q
+ TEST3=0
+ [[ 0 = 1 ]]
+ [[ 0 = 1 ]]
+ [[ 0 = 1 ]]

在线中,echo '191.35 < 191.254 && 191.35 > 188.1 'IP 191.35 小于 191.254,但是却不被视为 IP。

我尝试过在中使用双引号,TEST=$(echo "$i < $IP_BRD && $i > $IP_LOW " | bc -q )但没有取得太大成功。

有什么想法如何解决它吗?

答案1

在 echo '191.35 < 191.254 && 191.35 > 188.1 ' 行中,IP 191.35 小于 191.254,但它不被视为它。

不,不是:191.35 == 191.350 > 191.254。 bc 以数字方式比较它们,它不能直接比较 IP。您应该先将 IP 转换为整数。然后,您可以使用 shell 内置程序来比较它们,而无需借助外部工具。

编辑:查看此线程:IP地址转换器

答案2

如果您有 GNU 工具链,您可以使用 来识别一组值中的最低值sort。这也可以处理部分 IP 地址,如示例中的191.35和。187.254

printf "%s\0" 191.35 187.254 | sort -zV | head -zn 1 | tr -d '\0'

将其放入 shell 函数中,然后您可以使用相等测试来识别两个 IP 地址中较低的一个:

# Return the lowest of a set of IP addresses
lowIP() {
    printf "%s\0" "$@" | sort -zV | head -zn 1 | tr '\0' '\n'
}

# Sample session
try=191.35
if [[ $(lowIP "$try" 187.254) == "$try" ]]
then
    echo "$try is the lower value"
else
    echo "$try is not the lower value"
fi

答案3

你不需要bc在这里使用;你的 shell 可以处理 IPv4 地址的八位字节:

(
  IFS=.
  read i1 i2 i3 i4 <<< "$i"
  read b1 b2 b3 b4 <<< "$IP_BRD"
  read l1 l2 l3 l4 <<< "$IP_LOW"
  if [ "$i1" -le "$b1" -a "$i2" -le "$b2" -a "$i3" -le "$b3" -a "$i4" -lt "$b4" ] &&
    [ "$l1" -le "$i1" -a "$l2" -le "$i2" -a "$l3" -le "$i3" -a "$l4" -lt "$i4" ]
  then
    echo success
  else
    echo failure
  fi
)

如果你真的想要仅用于比较数字,然后生成以下形式的bc大语句:if

if (a < b)
  if (c < d)
    # ...
      1

即:

if [ "$(printf "if (%d <= %d) if (%d <= %d) if (%d <= %d) if (%d < %d) \n \
                if (%d <= %d) if (%d <= %d) if (%d <= %d) if (%d < %d) 1\n" \
        "$i1" "$b1" "$i2" "$b2" "$i3" "$b3" "$i4" "$b4" \
        "$l1" "$i1" "$l2" "$i2" "$l3" "$i3" "$l4" "$i4" | bc)" = 1 ]
then
  echo success
else
  echo failure
fi

相关内容