求助:Bash脚本实现网络地址与IP地址的验证方案
解决Bash中IP和CIDR地址验证的问题
首先,咱们先梳理下你原来脚本里的几个核心问题:
- 正则范围写法错误:
[1-255]这种格式在正则里是字符集,只会匹配1、2、5这几个单个字符,根本不是你想要的1到255的数字区间。同理,[8-32]也只会匹配8、3、2,无法覆盖8到32的合法CIDR后缀。 - 点号未转义:正则里的
.是匹配任意字符的通配符,必须写成\.才能匹配IP里的实际点分隔符,不然像192x168x1x0/24这种错误格式也会被误判。 - 语法逻辑问题:你的if语句缺少分号/换行分隔,而且如果是想判断“地址无效”时输出提示,需要加上
!(取反),正确语法应该是if ! [[ ... ]]; then ...; fi。
下面给你两种实用的解决方案,按需选择:
方案一:纯正则验证(Bash原生)
适合不想依赖外部命令的场景,用正则精确匹配IP和CIDR的合法格式:
#!/bin/bash # 定义匹配单个IP段(0-255)的正则片段 octet_regex='(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' # 验证单个IP地址(如192.168.1.1) validate_ip() { local ip="$1" if [[ "$ip" =~ ^$octet_regex\.$octet_regex\.$octet_regex\.$octet_regex$ ]]; then echo "✅ 有效的IP地址: $ip" return 0 else echo "❌ 错误: '$ip' 不是有效的IP地址" return 1 fi } # 验证CIDR网络地址(如192.168.1.0/24) validate_cidr() { local cidr="$1" # CIDR后缀限定为8-32之间的整数 if [[ "$cidr" =~ ^$octet_regex\.$octet_regex\.$octet_regex\.$octet_regex\/(8|9|[12][0-9]|3[012])$ ]]; then echo "✅ 有效的CIDR网络地址: $cidr" return 0 else echo "❌ 错误: '$cidr' 不是有效的CIDR网络地址" return 1 fi } # 处理输入参数 if [[ $# -eq 0 ]]; then echo "请提供要验证的IP或CIDR地址作为参数(例如:./script.sh 192.168.1.1 或 ./script.sh 192.168.1.0/24)" exit 1 fi # 根据输入格式自动选择验证方式 if [[ "$1" == */* ]]; then validate_cidr "$1" else validate_ip "$1" fi
正则说明:
octet_regex覆盖了0-255的所有合法数值:25[0-5]→ 匹配250-2552[0-4][0-9]→ 匹配200-249[01]?[0-9][0-9]?→ 匹配0-199(包含单个数字、两位数字的情况)
- CIDR部分的
\/(8|9|[12][0-9]|3[012])确保后缀是8到32之间的整数。
方案二:用系统ip命令验证(更可靠)
如果你的系统是Linux,ip命令可以直接验证IP和CIDR的有效性,甚至能处理边缘情况(比如0.0.0.0、255.255.255.255),比正则更稳妥:
#!/bin/bash if [[ $# -eq 0 ]]; then echo "请提供要验证的IP或CIDR地址作为参数" exit 1 fi # 让ip命令尝试解析地址,成功则说明有效 if ip route get "$1" >/dev/null 2>&1; then echo "✅ 有效的IP/CIDR地址: $1" else echo "❌ 无效的地址: $1" fi
这个方法的原理是借助系统自带的网络工具解析地址,避免正则可能遗漏的边界情况。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

