我正在编写一个验证 IP 地址的脚本。我这样做:
read pool
checkIp()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
checkIp $pool
if [ $? -eq 0 ]
then
echo "valid"
else
echo "invalid"
fi
问题是现在的要求是验证从第二个八位字节开始输入可以包含通配符“*”(我认为最好使用 CIDR 表示法,但事实并非如此),现在我不能使用,-le
因为如果有不是一个数字,它失败。
我尝试了一些表格,但所有转换都失败了。
答案1
进行一些额外的重写。 (当您使用特定于 Bash 的正则表达式时,只需填充数组BASH_REMATCH
而不是操作分词。)
checkIp()
{
local ip="$1"
if [[ "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3}|\*)\.([0-9]{1,3}|\*)\.([0-9]{1,3}|\*)$ ]]; then
for ((i=1;i<=4;i++)); do
[[ "${BASH_REMATCH[i]}" == '*' || "${BASH_REMATCH[i]}" -le 255 ]] || return 1
done
return 0
fi
return 1
}
更新根据业主评论禁止“*”后面的数字:
checkIp()
{
local ip="$1"
local asterisk=''
if [[ "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3}|\*)\.([0-9]{1,3}|\*)\.([0-9]{1,3}|\*)$ ]]; then
for ((i=1;i<=4;i++)); do
[[ "${BASH_REMATCH[i]}" == '*' || ( ! "$asterisk" && "${BASH_REMATCH[i]}" -le 255 ) ]] || return 1
[[ "${BASH_REMATCH[i]}" == '*' ]] && asterisk='1'
done
return 0
fi
return 1
}
答案2
作为记录,使用 zsh,您可以这样写:
[[ $ip = <0-255>.(<0-255>|"*").(<0-255>|"*").(<0-255>|"*") ]]
请注意,它允许000001.0000255.*.0
,但不允许0377.1.1.1
(即使0377
作为八进制数在范围内),因为它只考虑十进制数。