Bash 变量和类型

Bash 变量和类型

我正在编写一个验证 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作为八进制数在范围内),因为它只考虑十进制数。

相关内容