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/24
222.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