Dave
Dave

Reputation: 43

Breaking out of nested function loops in Bash

I am using a nested function to partition and making the filesystem for drives attached to a new Linux box. I am having a strange issue trying to break out of all loops.

I am keeping track of the nested loop index and using "break n". When the user replies "n" to the question "Do you have any additional drives to partition?" i expect to break out of all nested loops and continue with the script, but what happens is that the question gets asked again.

Can you help me figure this out?

INIT_STARTED=0
chooseDisks()
{
    INIT_STARTED=$((INIT_STARTED+1))    
    # Choosing which drive to work on
    read -p "Please type the name of the disk you want to partition: " DISK

    while true; do
        read -p "Are you sure you want to continue ? y (partition)/n (choose another drive) /x (continue) " ynx
        case $ynx in
            [Yy]* )
                containsElement "$DISK"
                if [ $? == 1 ]; then
                        initializeDisk $DISK 

                        # remove element from found disk to prevent trying to partition it again.
                        delete=($DISK)
                        FOUNDDISKS=( "${FOUNDDISKS[@]/$delete}" )                       
                else
                    echo "${red}$DISK is not a valid choice, please select a valid disk.${reset}"
                    chooseDisks
                fi

                break;;
            [Nn]* ) 
                chooseDisks
                break $((INIT_STARTED));;
            [Xx]* ) 
                return
                break;;
            * ) echo "Please answer y or n. x to continue the script.";;
        esac
    done

    # Any additional disks to partition?
    while true; do
        read -p "Do you have any additional drives to partition ? y/n " yn
        case $yn in
            [Yy]* )
                #chooseDisks $FOUNDDISKS
                chooseDisks
                break $((INIT_STARTED));;
            [Nn]* )
                return
                break $((INIT_STARTED));;
            * ) echo "Please answer y or n";;
        esac
    done

}

I expect this:

break $((INIT_STARTED));;

to end the nth loop and exiting the function.

Upvotes: 0

Views: 1637

Answers (3)

KamilCuk
KamilCuk

Reputation: 141010

i expect to break out of all nested loops and continue with the script

You can run the function in a subshell and use exit.

chooseDisks()
{
    if [ "$1" -eq 0 ]; then
        echo "The user entered it all!"
        exit 0
    fi

    echo "The user is still entering... $1"
    ( chooseDisks $(($1 - 1)) )
}

# Imagine the user 5 times enters something
( chooseDisks 5 )

But the best would be to refactor your code to just have a big while true; do loop in the beginning. There is no need to make this function recursive.

Upvotes: 0

Dave
Dave

Reputation: 43

I ended up changing the code to avoid breaking within a loop. Thanks guys for directing me the right way.

David

Upvotes: 1

Oleg Imanilov
Oleg Imanilov

Reputation: 2751

Don't play with nested logic break, just use some variable like $userStop and instead of while true; do put

userStop = false
while[!${userStop}]
do
#...
# replace break $((INIT_STARTED));; by
# userStop = true

Upvotes: 4

Related Questions