在Bash中比较两个IP地址

4

我想找出两个IP地址是否相同。我承认我对Bash不太熟悉,但我认为这应该可以实现:

if [[ "$IPAddress" != "$OLDIPAddress" ]]
then
  echo "IP Not the Same"
else
  echo "IP Same"
fi

为了测试目的,我甚至硬编码了两个变量的值,但它们仍然不显示为相同的值。我知道你有时看不到自己的笔误,但我不明白为什么这样做不能成功。有什么想法吗?


请展示一下 $IPAddress$OLDIPAddress 是如何定义的。 - jimm-cl
这取决于你所说的“相同”是什么意思...如果“127.0.0.1”和“127.000.000.001”是“相同”的,那么简单的文本比较将是不够的... - twalberg
1
@hek2mgl 并不是一定要考虑八进制,尽管那也是一个有效的观察... 我更多地考虑基于表单的输入,可能会返回每个八位字节的类似于 printf "%03d" x 的等效值... 不要相信输入... - twalberg
尝试将“0177.0.0.1 localhost”放入“/etc/hosts”文件中,@hek2mgl...在我的当前系统(Ubuntu 12.04.3)上无法正常工作。绝对不是普适的解决方法... - twalberg
@hek2mgl 我没有仔细跟进讨论,但在点十进制表示法中,每个数字都应该用十进制表示。例如,一些 IANA 表格 实际上显示了用零填充的三位数 十进制 的八位值。然而,_一些实现_(尤其是 BSD)允许使用 C 转换来表示八进制和十六进制。据我所知,这并没有被任何 RFC 强制执行。无论如何,由于这些实现已经广泛存在,建议删除前导 0 以避免歧义。有关详细信息,请参见 http://tools.ietf.org/html/draft-main-ipaddr-text-rep-00 - Sylvain Leroux
显示剩余8条评论
2个回答

4

虽然你的命令应该可以运行,但是你可以使用简单的测试运算符(只有一个方括号)。优点是它可以与任何(POSIX)shell一起使用。不过,[[ 运算符也应该可以工作。

你能重现这个小例子吗?(应该输出“yes”):

IPAddress="127.0.0.1"
OLDIPAddress="127.0.0.1"

if [ "$IPAddress" != "$OLDIPAddress" ] ; then 
    echo "no"
else
    echo "yes"
fi

1
这大致是我进行测试的方式。我得到的结果是,尽管它们明显相同,但这两个IP地址并不相同。由于某些我无法理解的原因,这个例子返回的结果不同... - CS3000911
你复制/粘贴了我的代码并尝试过吗?没有任何更改? - hek2mgl
是的。复制并粘贴,我只是在顶部添加了 #!/bin/bash。 - CS3000911

4

快速演示脚本,用于比较不同格式的IP地址,“常规”与DHCP始终为三位数的八位组。希望这里有一些有用的技巧可以用来解析和验证,以及比较,同时也会成为社区中更多技巧的催化剂。(这是我第一次带代码发布,希望它能正常显示 - 像往常一样,结果可能因人而异。)

#!/bin/bash
# demo.sh - parse, validate, compare ip addresses
# usage: demo.sh {ipaddress1} {ipaddress2}

#--- IP ADDRESS 1
#---   Is there anything besides digits and three dots?
#---   Parse out the octets
#---   There should be exactly 4 populated octets
#---   All 4 octets must not be > 255
[ "${1//[0-9]/}" != '...' ] && echo "invalid" && exit 1
O1=(${1//./ })
[ -z "${O1[3]}" -o -n "${O1[4]}" ] && echo "invalid" && exit 1
[ ${O1[0]} -gt 255 -o ${O1[1]} -gt 255 -o ${O1[2]} -gt 255 -o ${O1[3]} -gt 255 ] && echo "invalid" && exit 1
#--- IP ADDRESS 2
[ "${2//[0-9]/}" != '...' ] && echo "invalid" && exit 1
O2=(${2//./ })
[ -z "${O2[3]}" -o -n "${O2[4]}" ] && echo "invalid" && exit 1
[ ${O2[0]} -gt 255 -o ${O2[1]} -gt 255 -o ${O2[2]} -gt 255 -o ${O2[3]} -gt 255 ] && echo "invalid" && exit 1

#--- Numeric compares of each octet
echo "Comparing each octect"
if [ ${O1[0]} -eq ${O2[0]} ]
  then
    echo "  ${O1[0]} == ${O2[0]}"
  else
    echo "  ${O1[0]} != ${O2[0]}"
  fi
if [ ${O1[1]} -eq ${O2[1]} ]
  then
    echo "  ${O1[1]} == ${O2[1]}"
  else
    echo "  ${O1[1]} != ${O2[1]}"
  fi
if [ ${O1[2]} -eq ${O2[2]} ]
  then
    echo "  ${O1[2]} == ${O2[2]}"
  else
    echo "  ${O1[2]} != ${O2[2]}"
  fi
if [ ${O1[3]} -eq ${O2[3]} ]
  then
    echo "  ${O1[3]} == ${O2[3]}"
  else
    echo "  ${O1[3]} != ${O2[3]}"
  fi

#--- Numeric IP address compare
echo "Compare via long if"
if [ ${O1[0]} -eq ${O2[0]} -a ${O1[1]} -eq ${O2[1]} -a ${O1[2]} -eq ${O2[2]} -a ${O1[3]} -eq ${O2[3]} ]
  then
    echo "  ${1} == ${2}"
  else
    echo "  ${1} != ${2}"
  fi

#--- Loop for numeric compare
echo "Compare via loop"
SAME="Y"
for I in 0 1 2 3
  do
   echo "  loop ${I} compare ${O1[$I]} ${O2[$I]}"
   [ ${O1[$I]} -ne ${O2[$I]} ] && SAME="" && break
  done
echo "  result"
if [ -n "${SAME}" ]
  then
    echo "  ${1} == ${2}"
  else
    echo "  ${1} != ${2}"
  fi

exit


$ ./demo.sh 1.2.3.4 1.2.3
invalid
$ ./demo.sh 1.2.3.4 1.2.q.4
invalid
$ ./demo.sh 1.2.3.4 1.2.3.4.
invalid
$ ./demo.sh 1.2.3.4 1.2.3.4.5
invalid
$ ./demo.sh 1.2.3.4 1.2.300.4
invalid
$ ./demo.sh 1.02.3.004 01.2.003.4
Comparing each octect
  1 == 01
  02 == 2
  3 == 003
  004 == 4
Compare via long if
  1.02.3.004 == 01.2.003.4
Compare via loop
  loop 0 compare 1 01
  loop 1 compare 02 2
  loop 2 compare 3 003
  loop 3 compare 004 4
  result
  1.02.3.004 == 01.2.003.4
$ ./demo.sh 1.02.3.004 01.2.030.4
Comparing each octect
  1 == 01
  02 == 2
  3 != 030
  004 == 4
Compare via long if
  1.02.3.004 != 01.2.030.4
Compare via loop
  loop 0 compare 1 01
  loop 1 compare 02 2
  loop 2 compare 3 030
  result
  1.02.3.004 != 01.2.030.4
$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接