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