<> == How do I make a menu? == Some people like to use `select` because it's simple. If your own needs are extremely simple, then this may be sufficient for you. If you want your own look and feel, you can simply write a menu yourself. There is also [[BashFAQ/040|dialog]], which we won't cover on this page. === Using select === To use `select`, you need a list of choices. `select` will automatically assign numbers to the choices, and issue a prompt. You may customize the prompt. {{{ $ PS3='¿Qué es más macho? ' $ select ch in schoolbus lightbulb; do echo "You have chosen $ch!"; break; done 1) schoolbus 2) lightbulb ¿Qué es más macho? 45 You have chosen ! $ select ch in schoolbus lightbulb; do echo "You have chosen $ch!"; break; done 1) schoolbus 2) lightbulb ¿Qué es más macho? 2 You have chosen lightbulb! }}} If you check for an "empty" (invalid) selection inside the loop, then it becomes slightly less horrible: {{{ $ select ch in schoolbus lightbulb; do if [[ $ch ]]; then echo "You have chosen $ch!"; break; fi; done 1) schoolbus 2) lightbulb ¿Qué es más macho? 45 ¿Qué es más macho? 0 ¿Qué es más macho? 2 You have chosen lightbulb! }}} And that's `select`. Moving on.... === Writing your own menu === Just make a loop using `echo` and `read`. It's really that simple. Let's spice it up by making a multi-level menu ''application'' instead. {{{#!highlight bash #!/bin/bash main() { while true; do echo "== Make your selection:" echo "a) add" echo "s) subtract" echo "m) multiply" echo "q) quit" while true; do read -r -n1 -p "> " ch echo case $ch in a) add; break;; s) subtract; break;; m) multiply; break;; q) exit 0;; *) echo "Unrecognized command. Please try again.";; esac done done } add() { local a b while true; do echo "== Addition" echo "Enter first addend, or q to return to main menu." read -r -p "> " a [[ $a = q ]] && return echo "Enter second addend." read -r -p "> " b echo "$a + $b = $((a + b))" done } # subtract and multiply functions not shown main }}} You can make it as simple or as complex as you like. You can create your own input function to wrap `read` and persist until the user types a syntactically valid response. You can use `read -e` to allow the user to use readline editing features. It's all up to you.