此 bash 变量是有效的 IP v4 或 6 地址吗?

此 bash 变量是有效的 IP v4 或 6 地址吗?

我有一个名为 bash(来自最新 Debian 测试/bookworm apt 的 v5.2)变量TARGET。如何检查内容是否是有效的 IPv4 或 IPv6 地址,而不是类似的地址ERROR

答案1

您可以使用 bash 正则表达式执行简单的验证,以查看变量是否与预期格式匹配:

is_ipv4_address() {
  [[ $1 =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
}

使用上面的函数,我们可以运行这个脚本:

for data in 1.2 1.2.3 1.2.3.4; do
  echo -n "$data: "
  is_ipv4_address "$data" && echo yes || echo no
done

并得到输出:

1.2: no
1.2.3: no
1.2.3.4: yes

这是“松散”验证:即999.999.999.999匹配模式但不是有效地址。如果您需要更完整的解决方案,可以使用Linux 期刊文章关于这个话题。


IPv6 有点复杂:匹配完全展开的形式很简单,但这本身并没有什么好处,因为我们可以折叠零。

我们可以从这样的事情开始:

is_ipv6_address() {
  [[ $1 =~ ^([0-9a-fA-F]{0,4}:){0,7}[0-9a-fA-F]{1,4}$ ]]
}

与之前的解决方案一样,这是一个松散的匹配;这将要匹配实际上不是 ipv6 地址的内容,但根据您的需要,它可能就很好。以下是一些测试用例:

testcases=(
1.2.3.4
2001:foo
"i am not an ip address"
2001:0000:3238:DFE1:0063:0000:0000:FEFB
2001:0000:3238:DFE1:63:0000:0000:FEFB
2001:0000:3238:DFE1:63::FEFB
2001:0:3238:DFE1:63::FEFB
2c:f0:5d:c9:12:a9
)

for testcase in "${testcases[@]}"; do
  echo -n "$testcase: "
  is_ipv6_address "$testcase" && echo yes || echo no
done

以上输出:

1.2.3.4: no
2001:foo: no
i am not an ip address: no
2001:0000:3238:DFE1:0063:0000:0000:FEFB: yes
2001:0000:3238:DFE1:63:0000:0000:FEFB: yes
2001:0000:3238:DFE1:63::FEFB: yes
2001:0:3238:DFE1:63::FEFB: yes
2c:f0:5d:c9:12:a9: yes

所以我们可以看到它匹配有效的 ipv6 地址格式,拒绝明显错误的格式,但匹配 MAC 地址。还有改进的空间,但希望这能为您提供一个起点。

答案2

有一个名为 的 Debian 软件包ipcalc-ng,其中包含一个可执行文件来检查 IP 地址的有效性。

$ ipcalc-ng -c ::xx; echo $?
ipcalc-ng: bad IPv6 address: ::xx
1
$ ipcalc-ng -c ::1; echo $?
0

相关内容