함수 결과가 포함된 While 루프 - BASH

함수 결과가 포함된 While 루프 - BASH

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

관련 정보