Search code examples
arraysbashargument-passing

Create bash select menu with array argument


I have a function called createmenu. This function will take in an array as the first argument. The second argument will be the size of the array.

I then want to create a select menu using the elements of that array. This is what I have so far:

Create the menu with the given array

createmenu ()
{
  echo $1
  echo "Size of array: $2"
  select option in $1; do
    if [ $REPLY -eq $2 ];
    then
      echo "Exiting..."
      break;
    elif [1 -le $REPLY ] && [$REPLY -le $2-1 ];
    then
      echo "You selected $option which is option $REPLY"
      break;
    else
      echo "Incorrect Input: Select a number 1-$2"
    fi
  done
}

This is an example call to the function:

createmenu ${buckets[*]} ${#buckets[@]}

How do I create this select menu using the elements of the argument array as options?


Solution

  • My suggestion would be to invert the order of your arguments (though you don't even need the length argument but we'll get to that) and then pass the array as positional parameters to the function.

    createmenu ()
    {
      arrsize=$1
      echo "Size of array: $arrsize"
      echo "${@:2}"
      select option in "${@:2}"; do
        if [ "$REPLY" -eq "$arrsize" ];
        then
          echo "Exiting..."
          break;
        elif [ 1 -le "$REPLY" ] && [ "$REPLY" -le $((arrsize-1)) ];
        then
          echo "You selected $option which is option $REPLY"
          break;
        else
          echo "Incorrect Input: Select a number 1-$arrsize"
        fi
      done
    }
    
    createmenu "${#buckets[@]}" "${buckets[@]}"
    

    Note I also fixed a couple of errors in your function. Namely that you'd missed some spaces between [ and the first argument and that [ isn't an arithmetic context so you need to force one for your math to work).

    But back to my comment before about not needing the length argument at all.

    If you are using the positional parameters for the array elements then you already have the length... in $# and can just use that.

    createmenu ()
    {
      echo "Size of array: $#"
      echo "$@"
      select option; do # in "$@" is the default
        if [ "$REPLY" -eq "$#" ];
        then
          echo "Exiting..."
          break;
        elif [ 1 -le "$REPLY" ] && [ "$REPLY" -le $(($#-1)) ];
        then
          echo "You selected $option which is option $REPLY"
          break;
        else
          echo "Incorrect Input: Select a number 1-$#"
        fi
      done
    }
    
    createmenu "${buckets[@]}"