3

I would like to compare the result (0 or 1) of a function in a while loop. Function validmask checks whether the entered input is in mask format. If so I get 1, and if not I get 0.

I want to run the mask=$(whiptail ...) command and check the value of $mask with thevalidmask` function until it returns a valid mask.

My problem is that I can't run the function again; my script exits after a single run. I know I have to put the function in the if statement, but I don't know how. Or is there better solution?

Here is the code:

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 

ADDED Function 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 } 

Also in loop while should be check if mask is valid or not. I got aboveif validmask $mask; then stat2='1'; else stat2='0'; fi code what checks empty input.

while [[ -z "$mask" ]] do mask=$(whiptail --title "xx" --inputbox --nocancel "Mask" 3>&1 1>&2 2>&3) done 

If I start my script I am able to fill in just one time a mask. A function validmask is not executed again.

9
  • 1
    Please edit your question and show us the entire script. Where is validmask defined? How does it work? What is it doing in the while loop?
    – terdon
    CommentedDec 28, 2015 at 15:33
  • Thanks for the edit. It's still not very clear though. What exactly are you looping for? Do you want to repeat the whiptail command until you get a valid mask? Do you want to repeat it for ever?
    – terdon
    CommentedDec 28, 2015 at 15:51
  • Yes exactly. Until I get valid mask. Plus input won't be empty.
    – Michal N.
    CommentedDec 28, 2015 at 15:56
  • Your validmask() function doesn't validate correctly.
    – pawel7318
    CommentedDec 28, 2015 at 17:28
  • @pawel7318 what do you mean not correctly? It returns 1 if mask is valid (e.g. 255.255.255.0), returns 0 (2555555.555.552.99)
    – Michal N.
    CommentedDec 28, 2015 at 17:53

3 Answers 3

3

Your first problem is:

while validmask do ... 

Nothing ever happens there - you call your function without any arguments. And so it returns false and the loop stops.

The next problem is you want to run your function until the return is valid. To do that, you need to use until. I managed to overlook this before.

You need to drop the first if statement and just do:

until validmask "$mask" do mask=$(get_new_value) done 

The until loop is the boolean negation of the while. It will run until the command it runs returns true.

It can also be written:

while ! validmask "$mask" do mask=$(get_new_mask) done 

You might do the assignment / test at once:

unset mask until validmask "${mask:=$(get_new_value)}" do mask= done 

Another problem is that your validmask function fails to fully validate for a lot of edge cases - especially those which include [*?. I think you should just be using case and nevermind all of the ancillary splitting and variable declarations.

Just rule out bad values:

validmask() case "${1##*[!0-9.]*}" in (.*|*.|*..*|*.*.*.*.*|*[!.][!.][!.][!.]*) ! :;; (*[3-9][!.][!.]*|*2[6-9][!.]*|*25[6-9]*) ! :;; (*.*.*.*) ;; (*) ! :;; esac 

A little demo:

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 

Here's another version of validmask() which, as I think, actually validates the masks. I didn't realize before that the netmasks were so restrictive.

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 
0
    2

    Just run the whiptail command once and save the mask. Check if it is valid and, if not, repeat until it is:

    ## 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 
    0
      1

      Just move your if statement to your while loop.

      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 
      4
      • Shoudn't it be while true?
        – muru
        CommentedDec 28, 2015 at 15:28
      • I used your code but I got an error "command not found" I guess I got wrong function. I am enclosing a screen of code function. [link]postimg.org/image/jmkr7a8mb
        – Michal N.
        CommentedDec 28, 2015 at 15:30
      • @muru Meanwhile I used your advice I get looped.
        – Michal N.
        CommentedDec 28, 2015 at 15:31
      • My bad, I've fixed the code.
        – Kira
        CommentedDec 28, 2015 at 15:34

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.