Обрабатывайте аргументы с помощью bash
, а не внешних процессов
for ARG in "${PARGS_ARR[@]}"
do
# trim single quotes
ARG=${ARG//\'}
# split by equals sign
IFS="=" read ARGL ARGR <<< "$ARG"
if [[ "$ARGL" == "-DnodeId" ]]; then
NODE=$ARGR
fi
done
Для правильной обработки проверки IP-адреса или CIDR используйте специально созданную для этого библиотечную функцию, такую как cidrvalidate()
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, охватывающего всю длину данной строки.
Другой очевидный способ сделать это — прочитать числа в заданной строке и проверить, находятся ли первые четыре в диапазоне 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
Здесь мы читаем пять слов в пять переменных. Введенная строка разбивается на слова .
и /
при чтении (, что означает, что 3/3/3/3.2
будет проанализировано как допустимое, но см. $ipaddr
в коде ). Любые считанные целочисленные данные, отличные от -, вызовут выход сценария. Затем мы начинаем проверять их значения на соответствие допустимым диапазонам. Если какой-либо тест не пройден, введенный адрес недействителен.