Search code examples
bashselectcase

How to replace/populate a bash case statement automatic


How to improve the following batch script by making so whenever a new script is added into the directory, it doesn't require to manually hardcode an extra line of code in script. like: 3) source $(pwd)/script-3.sh; myfunc;;

script:

#Menu script
title="Menu"
prompt="Pick an option(number): "

#options=(         
#        "script-1.sh" \
#        "script-2.sh" \
#        "script-3.sh" \
#         )

path=$(pwd) 
array=($path/*.sh)
options=( "${array[@]##*/}" )


echo "$title"
PS3="$prompt"
select opt in "${options[@]}" "Quit"; do 
    case "$REPLY" in
    1) source $(pwd)/script-1.sh; myfunc;;
    2) source $(pwd)/script-2.sh; myfunc;;
    3) source $(pwd)/script-3.sh; myfunc;;

    $((${#options[@]}+1))) echo "Goodbye!"; break;;
    *) echo "Invalid option. Try another one.";continue;;
    esac
done

How to automate this part ?

select opt in "${options[@]}" "Quit"; do 
    case "$REPLY" in
    1) source $(pwd)/script-1.sh; myfunc;;
    2) source $(pwd)/script-2.sh; myfunc;;
    3) source $(pwd)/script-3.sh; myfunc;;

    $((${#options[@]}+1))) echo "Goodbye!"; break;;
    *) echo "Invalid option. Try another one.";continue;;
    esac
done

this is the current manual part, where need to be hard-coded a value everytime a new script is added.

for example, lets say I added a new script called" script-99.sh

then it would need to hardcode it in the main script like this:

    case "$REPLY" in
    1) source $(pwd)/script-1.sh; myfunc;;
    2) source $(pwd)/script-2.sh; myfunc;;
    3) source $(pwd)/script-3.sh; myfunc;;
    4) source $(pwd)/script-99.sh; myfunc;;  ##Had to hardcode this line

Solution

  • A simple solution would be

    select opt in "${options[@]}" "Quit"; do
      script=script-$REPLY.sh
      if [[ -f $script ]]
      then
        source $script
      else
        echo Goodbye
        break
      fi
    done
    

    This also catches the case that someone deletes a script while the select-loop is still in process.

    A more stable solution would be

    quitstring=Quit
    select opt in "${options[@]}" $quitstring; do
      [[ $opt == $quitstring ]] && break
      source $opt
    done