bash select menu

In this tutorial, we will cover the basics of the select construct in Bash. The select construct allows you to generate menus.

Bash select constructs

The select construct generates a menu from a list of items. It has almost the same syntax as the for loop.

1
2
3
4
select ITEM in [LIST]
do
  [COMMANDS]
done

[LIST] can be a series of strings separated by spaces, number ranges, command output, arrays, etc. Custom prompts for select constructs can be set using the PS3 environment variable.

When the select construct is called, each item in the list will be printed on the screen (standard error) with a number.

If the number entered by the user corresponds to the number of one of the displayed items, the value of [ITEM] is set to that item. The value of the selected option is stored in the variable REPLY. Otherwise, if the user input is empty, the prompt and menu list are displayed again.

The select loop will continue to run and prompt the user for input until the break command is executed.

To demonstrate how the select construct works, let’s look at the following simple example.

1
2
3
4
5
6
7
PS3="Enter a number: "

select character in Sheldon Leonard Penny Howard Raj
do
    echo "Selected character: $character"
    echo "Selected number: $REPLY"
done

The script will display a menu consisting of a list of items with accompanying numbers and a PS3 prompt. When the user enters a number, the script will print the selected character and number.

1
2
3
4
5
6
7
8
9
1) Sheldon
2) Leonard
3) Penny
4) Howard
5) Raj
Enter a number: 3
Selected character: Penny
Selected number: 3
Enter a number:

Bash select example

Usually, select is used in combination with case in an if expression.

Let’s look at a more practical example. It is a simple calculator that prompts the user for input and performs basic arithmetic operations, such as addition, subtraction, multiplication, and division.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
PS3="Select the operation: "

select opt in add subtract multiply divide quit; do

  case $opt in
    add)
      read -p "Enter the first number: " n1
      read -p "Enter the second number: " n2
      echo "$n1 + $n2 = $(($n1+$n2))"
      ;;
    subtract)
      read -p "Enter the first number: " n1
      read -p "Enter the second number: " n2
      echo "$n1 - $n2 = $(($n1-$n2))"
      ;;
    multiply)
      read -p "Enter the first number: " n1
      read -p "Enter the second number: " n2
      echo "$n1 * $n2 = $(($n1*$n2))"
      ;;
    divide)
      read -p "Enter the first number: " n1
      read -p "Enter the second number: " n2
      echo "$n1 / $n2 = $(($n1/$n2))"
      ;;
    quit)
      break
      ;;
    *) 
      echo "Invalid option $REPLY"
      ;;
  esac
done

After executing the script, the menu and the PS3 prompt will be displayed. The user is prompted to select an action and then enter two numbers. Based on the user’s input, the script will print the result. After each selection, the user will be asked to perform a new action until the break command is executed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
1) add
2) subtract
3) multiply
4) divide
5) quit
Select the operation: 1
Enter the first number: 4
Enter the second number: 5
4 + 5 = 9
Select the operation: 2
Enter the first number: 4
Enter the second number: 5
4 - 5 = -1
Select the operation: 9
Invalid option 9
Select the operation: 5

One drawback of this script is that it can only be used with integers.

Here is a more advanced version. We use the bc tool, which supports floating point numbers, to perform mathematical calculations. Again, the repetition code is grouped in the function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
calculate () {
  read -p "Enter the first number: " n1
  read -p "Enter the second number: " n2
  echo "$n1 $1 $n2 = " $(bc -l <<< "$n1$1$n2")
}

PS3="Select the operation: "

select opt in add subtract multiply divide quit; do

  case $opt in
    add)
      calculate "+";;
    subtract)
      calculate "-";;
    multiply)
      calculate "*";;
    divide)
      calculate "/";;
    quit)
      break;;
    *) 
      echo "Invalid option $REPLY";;
  esac
done
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
1) add
2) subtract
3) multiply
4) divide
5) quit
Select the operation: 4
Enter the first number: 8
Enter the second number: 9
8 / 9 =  .88888888888888888888
Select the operation: 5  

Conclusion

The select construct allows you to easily generate menus. It is especially useful when writing shell scripts that require user input.