Bash의 IP 주소/CIDR에 대한 정규식

Bash의 IP 주소/CIDR에 대한 정규식

bash에서 사용자 입력이 유효한 IP 주소/CIDR인지 확인하고 이를 위해 정규식을 사용하고 있습니다. 따라서 IP의 유효한 CIDR은 0-32여야 하므로 (1-254).(1-255).(1-255).(1-255)/(1-32)현재 코드는 다음과 같습니다.

read -p "Input: " ip_address

if [[ $ip_address =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]];
    then
    echo "VALID"
else
    echo "NOT VALID"
fi

그러나 이는 지나치게 관대하며 일부 비효율적인 조합을 허용합니다. 따라서 유효한 IP 주소/CIDR 조합은 다음과 같습니다. 10.11.11.11/24또는 첫 번째 옥텟이 255보다 높거나 여기의 CIDR이 32보다 높기 때문에 254.255.255.255/23유효하지 않습니다 . 정규식 외에 유효한 IP 주소/CIDR을 확인하는 다른 방법이 있습니까?256.19.11.11/24222.222.222.222/33

답변1

cidrvalidate()IP 주소 또는 CIDR 확인을 올바르게 처리하려면 모듈 의 Perl 함수 와 같이 이 목적을 위해 특별히 설계된 라이브러리 함수를 사용하십시오 Net::CIDR.

$ perl -MNet::CIDR=cidrvalidate -e 'printf("%s\n", cidrvalidate($ARGV[0]) ? "valid" : "invalid")' -- 1.2.3.0/24
valid

$ perl -MNet::CIDR=cidrvalidate -e 'printf("%s\n", cidrvalidate($ARGV[0]) ? "valid" : "invalid")' -- 1.2.3.0/2
invalid

$ perl -MNet::CIDR=cidrvalidate -e 'printf("%s\n", cidrvalidate($ARGV[0]) ? "valid" : "invalid")' -- 1.2.3.0
valid

perldoc Net::CIDR이 라이브러리가 무엇을 할 수 있는지 알아보세요 .

위의 예에서는 --필요 하지 않지만 사용자의 모든 입력에 사용할 수 있습니다. 그렇지 않은 경우 perl로 시작하면 옵션으로 처리됩니다 -.

아래 방법은 시도한 방법의 변형이며 유효하지 않은 넷마스크에 대해서는 신경 쓰지 않습니다.


0에서 255 사이의 양의 십진수는 다음과 같이 일치될 수 있습니다.

[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]

0에서 32 사이의 양의 십진수는 다음과 같이 일치될 수 있습니다.

[0-9]|[12][0-9]|3[012]

이것을 사용하십시오 :

#!/bin/bash

n='([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
m='([0-9]|[12][0-9]|3[012])'

IFS= read -rp 'Input: ' ipaddr

if [[ $ipaddr =~ ^$n(\.$n){3}/$m$ ]]; then
    printf '"%s" is a valid CIDR\n' "$ipaddr"
else
    printf '"%s" is not valid\n' "$ipaddr"
fi

표현 방식

^$n(\.$n){3}/$m$

주어진 문자열의 전체 길이에 걸쳐 유효한 CIDR로 확장되는 전체 정규식입니다.


또 다른 확실한 방법은 읽는 것입니다.숫자주어진 문자열에서 처음 4개가 0-255 범위에 있고 다섯 번째가 0-32 범위에 있는지 테스트합니다.

#!/bin/bash

IFS='./' read -rp 'Input: ' a b c d e

for var in "$a" "$b" "$c" "$d" "$e"; do
    case $var in
        ""|*[!0123456789]*) 
            printf 'not a valid number: %s\n' "$var"
            exit 1
    esac
done

ipaddr="$a.$b.$c.$d/$e"

if [ "$a" -ge 0 ] && [ "$a" -le 255 ] &&
   [ "$b" -ge 0 ] && [ "$b" -le 255 ] &&
   [ "$c" -ge 0 ] && [ "$c" -le 255 ] &&
   [ "$d" -ge 0 ] && [ "$d" -le 255 ] &&
   [ "$e" -ge 0 ] && [ "$e" -le 32  ]
then
    printf '"%s" is a valid CIDR\n' "$ipaddr"
else
    printf '"%s" is not valid\n' "$ipaddr"
fi

여기서는 5개의 단어를 5개의 변수로 읽습니다. 입력 문자열은 읽을 때 .단어로 분할됩니다 /. 즉, 3/3/3/3.2유효한 것으로 구문 분석되지만 $ipaddr코드를 볼 수 있습니다. 정수가 아닌 데이터를 읽으면 스크립트가 종료됩니다. 그런 다음 유효한 범위에 대해 해당 값을 테스트하기 시작합니다. 테스트에 실패하면 입력한 주소가 유효하지 않은 것입니다.

답변2

이것이 내가 사용하는 것입니다:

#!/bin/bash
function checkCidrFormat {
  local ipCidr="${1}"
  local validIpCidr
  validIpCidr='(^([1-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\/([1-9]|[1-2][0-9]|[3][0-2]))$'
  if [[ $ipCidr =~ ^$validIpCidr ]]; then
    echo "valid format"
    return 0
  else
    echo "not valid format"
    return 1
  fi
}

while true;
do
read -rp "ip cidr (eg. 172.16.16.32/27): " cidr
if checkCidrFormat "${cidr}"; then
  echo "do something"
fi
done

관련 정보