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 の正の 10 進数は、次のように一致することができます。
[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]
0から32までの正の10進数は、次のように一致することができます。
[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の範囲にあり、5番目が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