我正在尝试使用 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