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() {
  max=5
  [ "$#" -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"
  done
}

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
#!/bin/bash

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
    else
        user_in="$(( REPLY - 1 ))"
        break
    fi
done

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

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]}"
    fi
done

or even

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

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

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

$ bash script.sh
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
#!/bin/bash
PROMPT=(1 2 3 4 5)
for i in ${PROMPT[*]}
do
    printf " %dn" $i
done
echo "Choose an option: "

read var

unset PROMPT[$var-1]
PROMPT_new=(${PROMPT[@]})

for n in ${PROMPT_new[*]}
do
    echo `command $var $n`
done
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.