select
can do most of this for you, without much effort needed.
How do I turn list of files into this array thingy?
You don't actually need to. select
takes a series of words to display as options. These can be given directly (select color in red green blue
) or come from the expansion of a file glob (select file in *.war
), as well as expanding an array into words as the example you found does (select option in "${options[@]}"
).
How do I get string at certain offset in options?
select
does this automatically, and stores it into the variable you provide. (If the user's input is invalid, it stores the empty string.)
How do I ensure user is asked to try again?
Again select
does this for you, because select makes a loop, like while
. It will keep asking until you break
out of the loop (or until it reads EOF, usually entered by Ctrl+D).
Can I allow for string stop
to stop selection mode?
Yes, the user's input is put in the variable REPLY
, regardless of whether it corresponds to one of the options, so you can check for specific values and handle them differently.
Putting it all together:
echo "The following `*.war` archives were found; select one:"
# set the prompt used by select, replacing "#?"
PS3="Use number to select a file or 'stop' to cancel: "
# allow the user to choose a file
select filename in *.war
do
# leave the loop if the user says 'stop'
if [[ "$REPLY" == stop ]]; then break; fi
# complain if no file was selected, and loop to ask again
if [[ "$filename" == "" ]]
then
echo "'$REPLY' is not a valid number"
continue
fi
# now we can use the selected file
echo "$filename installed"
# it'll ask for another unless we leave the loop
break
done
war
directory?