Creating Interactive Command-Line Menus in Bash
Introduction
When working with automation scripts, system maintenance, or dev tools, Bash remains one of the most flexible environments available. While plain command-line tools are powerful, making them interactive adds a new level of usability. An interactive menu allows users to make selections and trigger specific commands dynamically — all within the terminal. In this tutorial, we’ll explore how to build interactive command-line menus in Bash using a mix of shell scripting features such as loops, conditional statements, and functions.
1. Building a Basic Menu Structure
The simplest version of a menu in Bash involves displaying options and reading user input with read. The following example creates a basic menu that lets users choose one of three options:
#!/bin/bash
while true; do
echo "\n=== Main Menu ==="
echo "1. Show current date"
echo "2. List files"
echo "3. Exit"
read -p "Enter your choice [1-3]: " choice
case $choice in
1)
date
;;
2)
ls -lh
;;
3)
echo "Goodbye!"
break
;;
*)
echo "Invalid choice. Please try again."
;;
esac
done
Here, we use a while true loop to continuously display the menu until the user chooses to exit. The case statement cleanly manages each possible input.
2. Modularizing Logic with Functions
As menus become larger, using functions helps to keep the code organized and reusable. You can define separate functions for each task, and then call them inside the case structure:
#!/bin/bash
function show_date() {
echo "Current Date and Time: $(date)"
}
function list_files() {
echo "Listing contents of $(pwd):"
ls -lh
}
function system_info() {
echo "System Info:"
uname -a
}
while true; do
echo "\n=== Menu ==="
echo "1. Show Date"
echo "2. List Files"
echo "3. System Info"
echo "4. Exit"
read -p "Your choice: " choice
case $choice in
1) show_date ;;
2) list_files ;;
3) system_info ;;
4) break ;;
*) echo "Invalid choice" ;;
esac
done
Functions make it simple to scale up your script, add error handling, or integrate with external tools later on.
3. Using ‘select’ for Built-in Menus
Bash provides a built-in command, select, that simplifies creating numbered menus automatically. It is especially useful when you don’t want to manage menu numbering manually:
#!/bin/bash
PS3="Please select an option: "
select opt in "Show Date" "List Files" "Exit"; do
case $REPLY in
1) date ;;
2) ls -lh ;;
3) echo "Exiting..."; break ;;
*) echo "Invalid choice. Try again." ;;
esac
done
The select loop handles menu numbering automatically and uses $REPLY to capture the user’s input. You can also customize the PS3 prompt to your liking.
4. Handling Dynamic Commands and External Scripts
You can take interactivity further by dynamically invoking scripts or commands based on user input. Suppose you have multiple automation scripts in a directory — you can create a dynamic selection menu:
#!/bin/bash
scripts=(./scripts/*.sh)
PS3="Choose a script to run: "
select script in "${scripts[@]}" "Exit"; do
if [[ $REPLY -gt 0 && $REPLY -le ${#scripts[@]} ]]; then
echo "Running $script..."
bash "$script"
elif [[ $REPLY -eq $((${#scripts[@]}+1)) ]]; then
echo "Goodbye!"
break
else
echo "Invalid choice. Try again."
fi
done
This menu automatically loads available scripts, saving time for teams maintaining multiple automation routines. It’s dynamic — no need to update the menu manually every time a new script is added.
5. Enhancing UX: Colors and Validation
A professional touch can make CLI menus more readable and friendly. Adding color output using ANSI codes improves usability:
#!/bin/bash
green='\033[0;32m'
red='\033[0;31m'
reset='\033[0m'
while true; do
echo -e "${green}\n--- Bash Menu ---${reset}"
echo "1. Check Disk Usage"
echo "2. Show Memory Usage"
echo "3. Quit"
read -p "Choice: " choice
if ! [[ $choice =~ ^[1-3]$ ]]; then
echo -e "${red}Error:${reset} Invalid input."
continue
fi
case $choice in
1) df -h ;;
2) free -h ;;
3) echo "Exiting..."; break ;;
esac
done
Here, we validate the user’s input using a regular expression and add color-coded feedback for errors. These small additions make your Bash menus easier to read and less error-prone.
Conclusion
Interactive command-line menus in Bash are invaluable for simplifying complex automation workflows, user interactions, and script management. By combining loops, conditionals, functions, and even colorized feedback, you can deliver a smooth CLI experience for both developers and administrators. Whether you’re automating server maintenance or providing utilities for developers, adding a friendly interface ensures your scripts are practical, maintainable, and enjoyable to use.
Useful links:

