Select Menus
Select loops create interactive menu systems that display numbered options and prompt users to make a choice. They're perfect for building user-friendly command-line interfaces, installation scripts, configuration tools, and any interactive Bash program. Select loops automatically handle menu display and user input, making them much simpler than manually coding menus with echo and read!
Basic Select Loop
A select loop automatically displays a numbered menu and prompts the user to choose. The syntax is similar to a for loop, but select creates an interactive menu.
Click Run to execute your code
# Basic select syntax
select variable in item1 item2 item3; do
# code to handle selection
break # Usually break after handling
done
# Example
PS3="Choose an option: "
select choice in "Option 1" "Option 2" "Option 3" "Quit"; do
echo "You chose: $choice"
break
done
# Output:
# 1) Option 1
# 2) Option 2
# 3) Option 3
# 4) Quit
# Choose an option: _
- Automatically displays numbered menu (1), 2), 3)...)
- Stores selected item in variable
- Stores selected number in
REPLY variable- Prompts user with
PS3 (default: "#? ")- Loop continues until
break is used
Customizing the Prompt with PS3
The PS3 variable controls the prompt text displayed when select is waiting for user input. Set it before your select statement.
# Default PS3 is "#? "
select item in a b c; do
break
done
# Prompt: #?
# Custom PS3
PS3="Please choose (1-3): "
select item in "Start" "Stop" "Restart"; do
break
done
# Prompt: Please choose (1-3):
# More descriptive prompt
PS3="Select an option [1-4]: "
options=("Install" "Uninstall" "Update" "Exit")
select opt in "${options[@]}"; do
break
done
- Set
PS3 before the select statement- Make prompts clear and indicate valid range
- Consider including example:
"Choose [1-4]: "
Using Select with Case Statements
Select loops are almost always used with case statements to handle different menu options. This is the most common pattern.
# Select with case statement
PS3="Choose an action: "
select action in "Start" "Stop" "Restart" "Status" "Exit"; do
case $action in
"Start")
echo "Starting service..."
break
;;
"Stop")
echo "Stopping service..."
break
;;
"Restart")
echo "Restarting service..."
break
;;
"Status")
echo "Service status: running"
break
;;
"Exit")
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid option. Please choose 1-5."
;;
esac
done
- Use
case statements with select- Include
*) default case for invalid input- Use
break after each valid selection (except Exit)- Use
exit for quit/exit option
Continuous Menus
By default, select loops continue until you use break. You can create menus that keep running until the user explicitly exits.
# Continuous menu (keeps looping)
PS3="Select option: "
select choice in "View files" "Edit file" "Delete file" "Exit"; do
case $choice in
"View files")
ls -la
# No break - menu continues
;;
"Edit file")
echo "Editing..."
;;
"Delete file")
echo "Deleting..."
;;
"Exit")
echo "Exiting..."
break # Exit select loop
;;
*)
echo "Invalid option"
;;
esac
# Menu prompts again automatically
done
echo "Goodbye!"
Using Arrays with Select
You can use arrays with select loops to make your menus more dynamic and maintainable.
# Using array with select
options=("Option 1" "Option 2" "Option 3" "Quit")
PS3="Choose: "
select opt in "${options[@]}"; do
case $opt in
"Option 1"|"Option 2"|"Option 3")
echo "You selected: $opt"
break
;;
"Quit")
echo "Exiting..."
exit 0
;;
*)
echo "Invalid selection"
;;
esac
done
Common Mistakes
1. Forgetting break, causing infinite menu
# Wrong - menu loops forever
select choice in "Start" "Exit"; do
case $choice in
"Start")
echo "Started"
# Missing break!
;;
"Exit")
exit 0
;;
esac
done # Keeps prompting forever
# Correct - break after handling
select choice in "Start" "Exit"; do
case $choice in
"Start")
echo "Started"
break # Exit menu after action
;;
"Exit")
exit 0
;;
esac
done
2. Not handling invalid input
# Wrong - no handling for invalid numbers
select choice in "Option 1" "Option 2"; do
case $choice in
"Option 1")
echo "One"
break
;;
"Option 2")
echo "Two"
break
;;
# Missing default case!
esac
done
# Correct - handle invalid input
select choice in "Option 1" "Option 2"; do
case $choice in
"Option 1")
echo "One"
break
;;
"Option 2")
echo "Two"
break
;;
*)
echo "Invalid option. Choose 1 or 2."
;;
esac
done
3. Not setting PS3, confusing prompt
# Wrong - default PS3 is "#? " (confusing)
select choice in a b c; do
break
done
# Prompt: #? (user doesn't know what to do)
# Correct - set clear PS3
PS3="Choose an option [1-3]: "
select choice in a b c; do
break
done
# Prompt: Choose an option [1-3]:
Exercise: Create an Interactive Menu
Task: Create a script with an interactive select menu!
Requirements:
- Create a select menu with at least 4 options
- Use a case statement to handle each option
- Set a custom PS3 prompt
- Include an Exit option
- Handle invalid input with a default case
- Use break appropriately (either after each action or create continuous menu)
Show Solution
#!/bin/bash
# Interactive menu example
PS3="Please choose an option [1-5]: "
select option in "Show current directory" "List files" "Show date" "Show user" "Exit"; do
case $option in
"Show current directory")
echo "Current directory: $(pwd)"
break
;;
"List files")
echo "Files in current directory:"
ls -lh
break
;;
"Show date")
echo "Current date: $(date)"
break
;;
"Show user")
echo "Current user: $USER"
break
;;
"Exit")
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid option. Please choose 1-5."
;;
esac
done
Summary
- Syntax:
select variable in list; do ... done - PS3: Controls the prompt text (set before select)
- Menu: Automatically displays numbered options
- Variable: Selected item stored in loop variable
- REPLY: Selected number stored in
$REPLY - Case: Use case statements to handle menu options
- Break: Use break to exit select loop after action
- Default: Use
*)to handle invalid input - Arrays: Can use arrays:
select opt in "${array[@]}" - Continuous: Omit break for menus that keep running
What's Next?
Excellent! You've completed the Control Flow module! You now know how to make decisions with if and case statements, iterate with for/while/until loops, control loop execution, and create interactive menus. Next up is Functions - learn how to organize your code into reusable blocks, pass arguments, return values, and create modular, maintainable scripts!
Enjoying these tutorials?