Variáveis e tipos de Bash

2

Estou fazendo um script que valida um endereço IP. Eu faço isso:

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

O problema é que agora o requisito é validar que a partir do segundo octeto a entrada possa conter o caractere curinga "*" (acho melhor usar a notação CIDR, mas não é o caso), e agora não posso usar -le porque, se não houver um número, ele falhará.

Eu tentei alguns formulários, mas todas as conversões falharam.

    
por X3MBoy 30.01.2013 / 14:58

2 respostas

3

Com um pouco de reescrita adicional. (Ao usar a expressão regular específica do Bash, basta preencher o array BASH_REMATCH em vez de manipular uma divisão de palavras.)

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
}

Atualizar de acordo com comentário do proprietário para não permitir números após “*”:

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
}
    
por 30.01.2013 / 15:15
2

Para o registro, com zsh, você pode escrever:

[[ $ip = <0-255>.(<0-255>|"*").(<0-255>|"*").(<0-255>|"*") ]]

Observe que ele permite 000001.0000255.*.0 , mas não 0377.1.1.1 (mesmo que 0377 , conforme considerado um número octal, esteja dentro do intervalo), porque ele considera apenas os números decimais.

    
por 30.01.2013 / 16:33