How can I create a select menu in a shell script?
Solution 1:
#!/bin/bash
# Bash Menu Script Example
PS3='Please enter your choice: '
options=("Option 1" "Option 2" "Option 3" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
Add break
statements wherever you need the select
loop to exit. If a break
is not performed, the select
statement loops and the menu is re-displayed.
In the third option, I included variables that are set by the select
statement to demonstrate that you have access to those values. If you choose it, it will output:
you chose choice 3 which is Option 3
You can see that $REPLY
contains the string you entered at the prompt. It is used as an index into the array ${options[@]}
as if the array were 1 based. The variable $opt
contains the string from that index in the array.
Note that the choices could be a simple list directly in the select
statement like this:
select opt in foo bar baz 'multi word choice'
but you can't put such a list in a scalar variable because of the spaces in one of the choices.
You can also use file globbing if you are choosing among files:
select file in *.tar.gz
Solution 2:
Using dialog
, the command would look like this:
dialog --clear --backtitle "Backtitle here" --title "Title here" --menu "Choose one of the following options:" 15 40 4 \ 1 "Option 1" \ 2 "Option 2" \ 3 "Option 3"
Putting it in a script:
#!/bin/bash
HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"
OPTIONS=(1 "Option 1"
2 "Option 2"
3 "Option 3")
CHOICE=$(dialog --clear \
--backtitle "$BACKTITLE" \
--title "$TITLE" \
--menu "$MENU" \
$HEIGHT $WIDTH $CHOICE_HEIGHT \
"${OPTIONS[@]}" \
2>&1 >/dev/tty)
clear
case $CHOICE in
1)
echo "You chose Option 1"
;;
2)
echo "You chose Option 2"
;;
3)
echo "You chose Option 3"
;;
esac
Solution 3:
Not a new answer per se, but since there's no accepted answer yet, here are a few coding tips and tricks, for both select and zenity:
title="Select example"
prompt="Pick an option:"
options=("A" "B" "C")
echo "$title"
PS3="$prompt "
select opt in "${options[@]}" "Quit"; do
case "$REPLY" in
1) echo "You picked $opt which is option 1";;
2) echo "You picked $opt which is option 2";;
3) echo "You picked $opt which is option 3";;
$((${#options[@]}+1))) echo "Goodbye!"; break;;
*) echo "Invalid option. Try another one.";continue;;
esac
done
while opt=$(zenity --title="$title" --text="$prompt" --list \
--column="Options" "${options[@]}")
do
case "$opt" in
"${options[0]}") zenity --info --text="You picked $opt, option 1";;
"${options[1]}") zenity --info --text="You picked $opt, option 2";;
"${options[2]}") zenity --info --text="You picked $opt, option 3";;
*) zenity --error --text="Invalid option. Try another one.";;
esac
done
Worth mentioning:
-
Both will loop until the user explicitly chooses Quit (or Cancel for zenity). This is a good approach for interactive script menus: after a choice is selected and action performed, menu is presented again for another choice. If choice is meant to be one-time only, just use
break
afteresac
(the zenity approach could be further reduced also) -
Both
case
are index-based, rather than value-based. I think this is easier to code and maintain -
Array is also used for
zenity
approach. -
"Quit" option is not among the initial, original options. It is "added" when needed, so your array stay clean. Afterall, "Quit" is not needed for zenity anyway, user can just click "Cancel" (or close the window) to exit. Notice how both uses the same, untouched array of options.
-
PS3
andREPLY
vars can not be renamed.select
is hardcoded to use those. All other variables in script (opt, options, prompt, title) can have any names you want, provided you do the adjustments
Solution 4:
You can use this simple script for creating options
#!/bin/bash echo "select the operation ************" echo " 1)operation 1" echo " 2)operation 2" echo " 3)operation 3" echo " 4)operation 4"
read n case $n in 1) echo "You chose Option 1";; 2) echo "You chose Option 2";; 3) echo "You chose Option 3";; 4) echo "You chose Option 4";; *) echo "invalid option";; esac