Shell case statement

echo -e "Select: \c"
read IN
pattern="1-20"
case $IN in
 [$pattern])
              echo "Selected: $IN"
              ;;
 *)
              echo "Invalid selection: $IN"
              ;;
esac
# sh test
Select: 10
Invalid selection: 10

# sh test
Select: 2
Selected: 2

When I select 1 - 9 it work ok, but with a two digit number it fails.

$pattern it not static as in the above sample its filled in a for loop, i just put it this way for simplicity.

What am I missing here?

EDIT:
actually I have found that on 0,1 and 2 pass. 0 should not pass.

if pattern="1-9" then 1 through 9 passes.

I think related case ability :frowning:
you can try this :o

# case $IN in
 [1-9])
              echo "Selected: $IN"
              ;;
 1[0-9])
              echo "Selected: $IN"
              ;;
 20)
              echo "Selected: $IN"
              ;;

 *)
              echo "Invalid selection: $IN"
              ;;
esac

The way its working is in a for loop I'm incrementing a counter for each guest in Xen and numbering each one, when I select the number I am having the script perform an action to that server number. So I would need them all in one case command.

I guess its like you said its a case related ability/bug. I dont see why 1-9 would work and 1-10 wouldn't though. :frowning:

Some more knowledge about RE might make you see why range 1-9 would work but 1-10 doesn't work as you expected.

If you want to match a double digit number you can not do it as you has been trying.
[1-9] matches any single number between 1 and 9, said digits included
[1-9][0-9] matches any two digits number as long as the first digit is between 1 and 9 and the second digit 0 through 9

Now [1-20] matches any single digit 1 through 2 or 0

(Off topic: Advisible to not give a shell script the same name as a unix command. In this case "test").

setopt -s extglob   # bash Only
case $IN in 
?(0)[1-9]|[1-9][1-9]|20) echo "Selected: $IN"          ;; 
                      *) echo "Invalid selection: $IN" ;; 
esac

Jean-Pierre.

I didn't actually use test, when I pasted the text in I changed the name of the script. But I agree. :stuck_out_tongue: