I want to create a menu with a script with multi choice . like :
1)
2)
3)
4)
5)
I can choose 1 , and 3 , and 5 in the same time .
I want to create a menu with a script with multi choice . like :
1)
2)
3)
4)
5)
I can choose 1 , and 3 , and 5 in the same time .
bash
's select
compound command doesn't directly support multiple choices, but you can still base your solution on it, taking advantage of the fact that whatever the user enters is recorded in the special $REPLY
variable:
#!/usr/bin/env bash
choices=( 'one' 'two' 'three' 'four' 'five' ) # sample choices
select dummy in "${choices[@]}"; do # present numbered choices to user
# Parse ,-separated numbers entered into an array.
# Variable $REPLY contains whatever the user entered.
IFS=', ' read -ra selChoices <<<"$REPLY"
# Loop over all numbers entered.
for choice in "${selChoices[@]}"; do
# Validate the number entered.
(( choice >= 1 && choice <= ${#choices[@]} )) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; }
# If valid, echo the choice and its number.
echo "Choice #$(( ++i )): ${choices[choice-1]} ($choice)"
done
# All choices are valid, exit the prompt.
break
done
echo "Done."
As for how the select
command normally works, with a single selection:
man bash
and look under the heading 'Compound Commands'This answer implements custom logic as follows:
select
command, dummy
, is ignored, and the $REPLY
variable is used instead, because Bash sets it to whatever the user entered (unvalidated).IFS=', ' read -ra selChoices <<<"$REPLY"
tokenizes the user-entered value:
<<<
) to the read
command,<space>
) as the [Internal] Field Separator (IFS=...
)
-a
) selChoices
; -r
simply turns off interpretation of \
chars. in the input for choice in "${selChoices[@]}"; do
loops over all tokens, i.e., the individual numbers the user chose.(( choice >= 1 && choice <= ${#choices[@]} )) || { echo "Invalid choice: $choice. Try again." >&2; continue 2; }
ensures that each token is valid, i.e., that it is a number between 1 and the count of choices presented.echo "Choice #$(( ++i )): ${choices[choice-1]} ($choice)"
outputs each choice and choice number
i
), which is incremented (++i
) using an arithmetic expansion ($((...))
) - since a variable defaults to 0
in an arithmetic context, the first index output will be 1
;${choices[choice-1]}
, i.e., the choice string indicated by the number entered, decremented by 1
, because Bash arrays are 0
-based; note how choice
needs no $
prefix in the array subscript, because a subscript is evaluated in an arithmetic context (as if inside $(( ... ))
), as above.($choice)
, the chosen number in parentheses.break
is needed to exit the prompt; by default, select
will keep prompting.