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 の正の 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

関連情報