我想在 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
添加 函数 validmask
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
循环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