Reputation: 7687
I am reading up on Select menus in Bash:
Making menus with the select built-in
I am quite confused when it comes to iterating over the options in the menu and would appreciate any feedback on this.
Using the code here as a starting point:
How can I create a select menu in a shell script?
We get the following output:
root@dev:~/# ./test.sh
1) Option 1
2) Option 2
3) Option 3
4) Quit
Please enter your choice: 1
you chose choice 1
Please enter your choice: 2
you chose choice 2
Please enter your choice: 4
root@dev:~/#
What I would like to try to do, is show the select options again once an option has been chosen, so the output would be like:
root@dev:~/# ./example.sh
1) Option 1
2) Option 2
3) Quit
Please enter your choice: 1
you chose choice 1
1) Option 1
2) Option 2
3) Quit
Please enter your choice: 2
you chose choice 2
1) Option 1
2) Option 2
3) Quit
Please enter your choice: 3
root@dev:~/#
So I have given this a Bash (L) and and tried to loop through the options (array?):
#!/bin/bash
PS3='Please enter your choice: '
options=("Option 1" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Option 1")
echo "you chose choice 1"
# Create an incrementing value
loop=1;
# Loop through each option
for option in ${options[@]} ; do
# Echo the option
echo "$loop) $option";
# Increment the loop
loop=$((loop+1));
done
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
But then I get an output like:
root@dev:~/# ./stumped.sh
1) Option 1
2) Quit
Please enter your choice: 1
you chose choice 1
1) Option
2) 1
3) Quit
Please enter your choice:
So it seems that the array values are separated by spaces here?
To my understanding: options=("Option 1" "Quit")
is creating an array of 2 values and not of 3 however it is being interpreted in Bash as 3 and I am not sure why.
Could someone enlighten me and explain why this is happening?
Upvotes: 1
Views: 2911
Reputation: 20022
When you want the numbered options shown each iteration, let select do that for you.
options=("Option one" "two" three "and number four" quit)
while true; do
select item in "${options[@]}" ; do
if [ -n "${item}" ]; then
break
fi
echo "Sorry, please enter a number as shown."
break
done;
if [[ "${item}" = "quit" ]]; then
break
fi
if [ -n "${item}" ]; then
echo "Your answer is ${item}"
fi
done
Upvotes: 0
Reputation: 76989
Let's create a function
that shows the menu and echoes the user's choice:
function show_menu {
select option in "${OPTIONS[@]}"; do
echo $option
break
done
}
Now, we can wrap that function
in a loop, and only break out if the user picked Quit
:
while true; do
option=$(show_menu)
if [[ $option == "Quit" ]]; then
break
fi
done
Voila!
Upvotes: 2