Home > Net >  Create an interactive Shell prompt menu from a dynamic list?
Create an interactive Shell prompt menu from a dynamic list?

Time:12-03

The following prompt should allow the user to make a selection based on the populated list that is outputted to an array, then prints the list with its index, and asks user to select a number from the list, then sets it to a variable.

Multiple devices detected, please select one from the list:
1. Device1
2. Device2
3. Device3

1
You have selected device Device1

The code below is not functional and has many syntax errors, first I would like the script to detect if the output of arr=($(ip ad|awk '/state UP/ {print $2}')) contains multiple entries, if so run the script, otherwise set a default value. The case statement is not dynamic however, if more then 2 cases like below it will fail, perhaps a loop?

host_interfaces()
{
   arr=($(ip ad|awk '/state UP/ {print $2}'))
   echo "Multiple devices detected, please select one from the list:"
   for i in "${!arr[@]}"; do
   printf "%s%s\n" "$i.  " "${arr[$i]}"
   done
   PS3='Please enter your choice: '
   select opt in "${arr[@]}"
   do
      case $opt in
            "1")
               echo "You have selected device $opt"
               export HOST_INTERFACE=$opt
               ;;
            "2")
               echo "You have selected device $opt"
               export HOST_INTERFACE=$opt
               ;;
            "Quit")
               break
               ;;
            *) echo "invalid option ;;
      esac
   done
}

CodePudding user response:

A solution:

#! /bin/bash

declare HOST_INTERFACE=

function host_interfaces() {
    local -a arr=($(ip ad | awk '/state UP/ {gsub(/:/, "", $2); print $2}'))
    if [ "${#arr[@]}" -eq 1 ]; then
        HOST_INTERFACE="${arr[0]}"
        return 0
    fi
    local opt=
    HOST_INTERFACE=
    echo "Multiple devices detected, please select one from the list:"
    PS3='Please enter your choice: '
    # Add "Quit" value to the items
    select opt in "${arr[@]}" Quit; do
        # "opt" does not contains the number but the associated value
        case $opt in
            "Quit")
                # 
                break
            ;;
            "")
                # No value found
                echo "invalid option"
            ;;
            *)
                echo "You have selected device $opt"
                export HOST_INTERFACE=$opt
                break
            ;;
        esac
    done
}

host_interfaces

CodePudding user response:

This, maybe?

host_interfaces()
{
  local opt='' h=''
  arr=($(ip ad|awk '/state UP/ {print $2}'))
  if [ "${#arr[@]}" -eq 1 ]; then
    echo "One single device detected"
    h="${arr[0]}"
  elif [ "${#arr[@]}" -gt 1 ]; then
    echo "Multiple devices detected, please select one from the list:"
    PS3='Please enter your choice: '
    select opt in "${arr[@]}" Quit
    do
      case "$opt" in
        "Quit")
          break
          ;;
        "")
          echo "Invalid choice"
          h=''
          ;;
        *)
          echo "You have selected device $opt"
          h="$opt"
          ;;
      esac
    done
  else
    echo "No device detected"
  fi
  echo "Selected device: ${h:-none}"
  export HOST_INTERFACE="$h"
  [ -z "$h" ] && return 1 || return 0
}

Note that the function returns 1 if no valid device was found or selected, else 0. So you can use it with:

if host_interfaces; then
  echo "HOST_INTERFACE = $HOST_INTERFACE"
else
  echo "No device selected"
fi
  • Related