How to prompt input from a user from a variable or bash array?

In a bash script, how would you script the following ?

USER_INPUT="1 2 3 4 5"
echo "Please select one of the following values: $USER_INPUT"
Prompt the user to choose a value in $USER_INPUT.
echo "command <user input> <iterate through remaining numbers not selected from $USER_INPUT>

For example, if the user selects “2”, the following commands are run.

command 2 1
command 2 3
command 2 4
command 2 5
Asked By: uihdff


Accept your input on the command line, not interactively. (Please!)

This is simple enough I would just use a shell function.

iter_the_command() {
  [ "$#" -eq 1 ] && [ "$1" -ge 1 ] && [ "$1" -le "$max" ] ||
    { printf 'Error: please pass a number from 1 to %dn' "$max" >&2;
      return 1;}
  for i in $(seq "$max"); do
    [ "$i" -eq "$1" ] && continue
    somecommand "$1" "$i"

However, I have a strong suspicion this is an XY question and what you’re really trying to do would be more easily accomplished directly. (In other words, I find it hard to imagine a scenario where the above code would actually be useful and perform a needed function not better done otherwise.)

Answered By: Wildcard

values=( "Why is" "a raven" "like a" "writing desk?" )

select word in "${values[@]}"; do
    if [[ -z "$word" ]]; then
        printf '"%s" is not a valid choicen' "$REPLY" >&2
        user_in="$(( REPLY - 1 ))"

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        printf 'You did not pick "%s"n' "${values[$i]}"

The select command will present the user with a menu of choices. Upon picking a menu item, $REPLY will be the number that the user entered, and $word will be the value in the menu corresponding to that number. If an invalid choice is made, $word will be empty.

The second part iterates over our array (which corresponds to your $USER_INPUT string) using the C-like for loop in bash. If we come upon the index that the corresponds to the chosen value, we skip it. We print out all other values from our array.

You may obviously execute commands in the loop to:

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        printf 'command %s %sn' "$user_in" "${values[$i]}"

or even

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        command "${values[$user_in]}" "${values[$i]}"

which will try to run the actual things in $values as a command.

Testing it (with the first version of the loop):

$ bash
1) Why is
2) a raven
3) like a
4) writing desk?
#? B
"B" is not a valid choice
#? 0
"0" is not a valid choice
#? 3
You did not pick "Why is"
You did not pick "a raven"
You did not pick "writing desk?"

If you can afford to modify $values, and just want to output the things that the user didn’t pick, then the second part of the script (the loop) may be replaced with

unset values[$user_in]
printf 'You did not pick "%s"n' "${values[@]}"
Answered By: Kusalananda
PROMPT=(1 2 3 4 5)
for i in ${PROMPT[*]}
    printf " %dn" $i
echo "Choose an option: "

read var

unset PROMPT[$var-1]

for n in ${PROMPT_new[*]}
    echo `command $var $n`
Answered By: Bussller
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.