whileループで関数(0または1)の結果を比較したいです。validmask
入力した内容がマスク形式であるか確認する機能です。それから私はそれを得ます1
。そうでなければ私はそれを得ます0
。
コマンドを実行して有効なマスクを返すまで、mask=$(whiptail ...)
validmask`関数の値を確認したいと思います。$mask with the
私の問題は、関数を再実行できないことです。スクリプトを一度実行した後は終了します。 if文の中に関数を入れなければならないことはわかりますが、どうすればいいのかわかりません。それとも、より良い解決策がありますか?
コードは次のとおりです。
if validmask $mask; then stat2='1'; else stat2='0'; fi
while validmask
do
if [[ $stat2 == 0 ]]; then
mask=$(whiptail --title "xx" --inputbox --nocancel "Bad entry" 3>&1 1>&2 2>&3)
fi
done
次へ追加 関数有効マスク
function validmask()
{
local mask=$1
local stat2=1
if [[ $mask =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
mask=($mask)
IFS=$OIFS
[[ ${mask[0]} -le 255 && ${mask[1]} -le 255 \
&& ${mask[2]} -le 255 && ${mask[3]} -le 255 ]]
stat2=$?
fi
return $stat2
}
また、whileループでマスクが有効であることを確認する必要があります。私は持っています以上 if validmask $mask; then stat2='1'; else stat2='0'; fi
空の入力を確認するコードです。
while [[ -z "$mask" ]]
do
mask=$(whiptail --title "xx" --inputbox --nocancel "Mask" 3>&1 1>&2 2>&3)
done
スクリプトを書き始めると、マスクは一度だけ埋めることができます。関数 validmask は再実行されません。
答え1
最初の質問は次のとおりです。
while validmask
do ...
何も起こりません。パラメータなしで関数を呼び出します。したがって、falseを返し、ループが停止します。
次の質問は関数を実行しますか?~まで返品は有効です。これを行うにはを使用する必要がありますuntil
。私は以前これを見落としました。
最初のステートメントを削除し、if
次の操作を行う必要があります。
until validmask "$mask"
do mask=$(get_new_value)
done
Loopはのuntil
ブール否定ですwhile
。実行するコマンドがtrueを返すまで実行されます。
次のように書くこともできます。
while ! validmask "$mask"
do mask=$(get_new_mask)
done
今課題/試験を完了できます。
unset mask
until validmask "${mask:=$(get_new_value)}"
do mask=
done
もう一つの問題は、あなたの関数が多くの極端なケースを完全に確認できないことです。validmask
特に。[*?
case
無効な値を除外してください。
validmask()
case "${1##*[!0-9.]*}" in
(.*|*.|*..*|*.*.*.*.*|*[!.][!.][!.][!.]*) ! :;;
(*[3-9][!.][!.]*|*2[6-9][!.]*|*25[6-9]*) ! :;;
(*.*.*.*) ;; (*) ! :;;
esac
小さなデモ:
for mask in \
0.0.0.0 \
0.0.0. \
0.0.0.1233 \
0.0.0.233 \
0.0..233 \
0.0.2.233 \
0.5555.2.233 \
0.55.2.233 \
.55.2.233 \
1.55.2.233 \
255.255.255.255 \
255.255.256.255
do validmask "$mask"
printf "%-16.16s: %.$?0s%.$((!$?*4))s\n%.d" \
"$mask" bad good "0$(($?*8))"
printf "printf's return:\t $?\n\n"
done 2>/dev/null
0.0.0.0 : good
printf's return: 0
0.0.0. : bad
printf's return: 1
0.0.0.1233 : bad
printf's return: 1
0.0.0.233 : good
printf's return: 0
0.0..233 : bad
printf's return: 1
0.0.2.233 : good
printf's return: 0
0.5555.2.233 : bad
printf's return: 1
0.55.2.233 : good
printf's return: 0
.55.2.233 : bad
printf's return: 1
1.55.2.233 : good
printf's return: 0
255.255.255.255 : good
printf's return: 0
255.255.256.255 : bad
printf's return: 1
これはvalidmask()
実際にマスクを検証する別のバージョンだと思います。ネットマスクがこんなに制限的なのか分からなかった。
validmask()
case ."${1##*[!.0124589]*}". in
(*.*.*.*.*.*.*|*[!.][!.][!.][!.]*) ! :;;
(*[!.25]*.[!0]*|*.[!012]*|*0[!.]*) ! :;;
(*1[!29]*|*1?[!28]*|*98*|*.2?.*) ! :;;
(*4[!.08]*|*[.2][25][!245]*) ! :;;
(.*.*.*.*.) echo "$1";; (*) ! :;;
esac
a=-1 b=0 c=0 d=0
for o in a b c d
do while [ "$(($o+=1))" -lt 1000 ] ||
! : "$(($o=255))"
do validmask "$a.$b.$c.$d"
done; done
0.0.0.0
128.0.0.0
192.0.0.0
224.0.0.0
240.0.0.0
248.0.0.0
252.0.0.0
254.0.0.0
255.0.0.0
255.128.0.0
255.192.0.0
255.224.0.0
255.240.0.0
255.248.0.0
255.252.0.0
255.254.0.0
255.255.0.0
255.255.128.0
255.255.192.0
255.255.224.0
255.255.240.0
255.255.248.0
255.255.252.0
255.255.254.0
255.255.255.0
255.255.255.128
255.255.255.192
255.255.255.224
255.255.255.240
255.255.255.248
255.255.255.252
255.255.255.254
255.255.255.255
答え2
コマンドを一度実行しwhiptail
てマスクを保存します。有効であることを確認し、そうでない場合は、次になるまで繰り返します。
## Get the 1st mask
mask=$(whiptail --title "xx" --inputbox --nocancel "Bad entry" 3>&1 1>&2 2>&3)
## If it isn't valid, repeat until it is
until validmask "$mask"; do
mask=$(whiptail --title "xx" --inputbox --nocancel "Bad entry" 3>&1 1>&2 2>&3)
done
答え3
あなたの声明をループif
に移してください。while
while true
do
if ! validmask $mask; then
mask=$(whiptail --title "xx" --inputbox --nocancel "Bad entry" 3>&1 1>&2 2>&3)
else
break
fi
done