Home > Enterprise >  Avoid persisting prompt in nested selection
Avoid persisting prompt in nested selection

Time:10-18

With this bash script the user should select a directory and depending on that doing a second selection of the subdirectories.

doSomething() {
    echo "finish"
}

PS3="Select project: "
options=( )
for n in ./apps/*/; do
    options =("$(basename "$n")")
done
select app in "${options[@]}"; do
    PS3="Select application: "
    options=()
    for n in ./apps/$app/*/; do
        appName=$(basename "$n")
        if [[ "$appName" != *-e2e ]]; then
            options =("$appName")
        fi
    done
    select project in "${options[@]}"; do
        doSomething $app $project
        break
    done
done

My problem is, that the prompt Select application keeps active even after the second selection. What am I missing?

CodePudding user response:

I personally tend to flatten the logic, because breaking free of nested loops isn't very common:

#!/bin/bash
shopt -s nullglob extglob

doSomething() { echo "finish"; }

PS3="Select project: "

options=( ./app/*/ )
options=( "${options[@]%/}" )
options=( "${options[@]##*/}" )

select app in "${options[@]}"
do
    [[ -n "$app" ]] && break
done

PS3="Select application: "

options=( ./app/"$app"/!(*-e2e)/ )
options=( "${options[@]%/}" )
options=( "${options[@]##*/}" )

select project in "${options[@]}"
do
    [[ -n "$project" ]] && break
done

doSomething "$app" "$project"

notes:

  • I set shopt -s nullglob so that unmatched globs don't expand to anything.

  • I'm using two bash Parameter Expansions for getting rid of the trailing / & the path prefix of each element in the options array.

  • I set shopt -s extglob for using the glob negation !(*-e2e).

aside: I'm not sure why you use PS3 instead of a simple echo, is there a reason for it?

  •  Tags:  
  • bash
  • Related