Bash Select (Make Menus)
This article will examine the fundamentals of the select construct in Bash.
The chosen construct enables you to build menus.
Bash select Construct
The chosen construct produces a menu from a list of items. It has nearly the same syntax as the for loop:
select ITEM in [LIST]
do
[COMMANDS]
done
The [LIST] may be a sequence of strings separated by spaces, a range of integers, output of a command, an array, and so on. A custom prompt for the chosen construct may be provided using the PS3 environment variable.
When the chosen construct is executed, each item from the list is written on the screen (standard error), prefixed by a number.
If the user inputs a number that corresponds to one of the shown items, then the value of [ITEM] is assigned to that item. The value of the chosen item is saved in the variable REPLY. Otherwise, if the user input is empty, the prompt and the options list are presented again.
The choose loop will continue to operate and request user input until the break instruction is invoked.
To show how the chosen construct works, let’s have a look at the following basic Example:
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 show a menu consisting of items with an associated number and the PS3 prompt. When the user inputs a number, the script will output the chosen character and number:
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, choose is used in connection with the case of if statements.
Let’s take a look at a more realistic scenario. A simple calculator asks the user for input and does basic arithmetic operations, including addition, subtraction, multiplication, and division.
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
The script shows the menu and the PS3 prompt when the script is performed. The user is invited to pick the procedure and input two digits. Depending on the user’s input, the script will output the outcome.
The user will be requested to complete a new action after each selection until the break instruction is invoked.
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 limitation of this script is that it can operate only with integers.
Here is a bit more sophisticated version. We utilize the bc tool that allows floating numbers to conduct mathematical computations. Also, the repetitious code is bundled within a function.
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
Output:
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 chosen construct enables you to design menus. It is convenient for building shell programs that need user input.