12

I am trying to implement a simple menu using the select command. The script (for testing purposes) is as follows:

#!/bin/bash
echo "*******************"
PS3='Select an option and press Enter: '
options=("apache" "named" "sendmail")
select opt in "${options[@]}"
do
  case $opt in
        "apache")
          date
          ;;
        "named")
          echo "test"
          ;;
        "sendmail")
          echo "test 2"
          ;;
        *) echo "invalid option";;
  esac
done
echo "*********************"

The script is not recognizing any valid inputs I give and always prints the "invalid option" message. What am doing wrong in this script?

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
Sumod
  • 597
  • 2
  • 6
  • 9

2 Answers2

14

Your menu shown by select will look like:

1) apache
2) named
3) sendmail
Select an option and press Enter: 

At this time, you enter "1" or "2" or "3": you don't type the word.

Also, select will loop until it sees a break command, so you want this:

  case $opt in
        "apache")
          date
          break
          ;;
        "named")
          echo "test"
          break
          ;;
        "sendmail")
          echo "test 2"
          break
          ;;
        *) echo "invalid option";;
  esac

If you wanted to allow the user to enter either the number or the word, you could write this:

select opt in "${options[@]}"; do
  case "$opt,$REPLY" in
    apache,*|*,apache)     do_something; break ;;
    named,*|*,named)       do_something; break ;;
    sendmail,*|*,sendmail) do_something; break ;;
  esac
done

The comma has no syntactical significance, it's just there to be able to pattern match on either the $REPLY variable (which is what the user actually typed) or the $opt variable

glenn jackman
  • 84,176
  • 15
  • 116
  • 168
  • The `select` command needs a `break`, not `case`. – glenn jackman Sep 14 '11 at 18:09
  • Thanks! I did not realize that it was numerical options. Duhh! – Sumod Sep 15 '11 at 10:45
  • Hah, I too program in C and, you do need a `break` there in every section. __However, you will never need a `break` in a *case...esac* block in a *shell script*.__ It can happen so easily to get them mixed up. :-) – syntaxerror Nov 20 '14 at 11:05
  • 1
    @syntaxerror, you're right, you don't need `break` for `case`. However, you need a `break` to escape the `select` loop. – glenn jackman Nov 20 '14 at 12:55
  • @glenn jackman I would like to have this turned into a more helpful comment (see next). So it would be great if you agreed on deleting your comment from 12:55. I will do the same with mine, of course. – syntaxerror Nov 23 '14 at 16:20
  • It is particularly important to note that the `break` statements in the code snippet shown are __not__ for `case`, but in order to prematurely exit that `select` block! While you will (um, generally) need a `break` even for each case in a switch-case block in C language, for shell scripts you *never* will. So if there was no `select`, all the `break` statements could be omitted as well (in shell scripting). Just wanted to point that out, as it can easily be misread. – syntaxerror Nov 23 '14 at 16:23
  • Clarification: `break` does not "prematurely" exit the `select` command -- `select` will loop forever unless "broken". – glenn jackman Nov 23 '14 at 19:11
3

Your $opt variable will be set to the option word corresponding to the number that the user inputs. If you want to look at what the user actually typed, look at $REPLY.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • 1
    Given that the `case` compares `$opt` against "apache", "named" and "sendmail", it is correct and nothing has to be changed. – manatwork Sep 14 '11 at 14:13
  • @manatwork, unless the OP wants the user to type in the words "apache", "named" or "sendmail" rather than pressing 1, 2 or 3. – Kusalananda Sep 14 '11 at 14:38
  • Interesting. $REPLY holds `1`/`2`/`3`, and $opt holds `apache`/`named`/`sendmail` – Peter.O Sep 15 '11 at 06:50
  • @fred, yes, `$REPLY` is whatever the user typed, and if it was a valid number then `$opt` will be the word corresponding to that number. – Kusalananda Sep 15 '11 at 06:53