How to re-run the case statement if the input is invalid?

10,397

Solution 1

Do your input in a loop. Exit the loop with break (or exit as the case may be) if you get a valid response from the user.

while true; do
    read -p 'Continue? yes/no: ' input
    case $input in
        [yY]*)
            echo 'Continuing'
            break
            ;;
        [nN]*)
            echo 'Ok, exiting'
            exit 1
            ;;
         *)
            echo 'Invalid input' >&2
    esac
done

As a utility function:

ask_continue () {
    while true; do
        read -p 'Continue? yes/no: ' input        
        case $input in
            [yY]*)
                echo 'Continuing'
                break
                ;;
            [nN]*)
                echo 'Ok, exiting'
                exit 1
                ;;
             *)
                echo 'Invalid input' >&2
        esac
    done
}

A variation of the utility function that allows exiting through EOF (e.g. pressing Ctrl+D):

ask_continue () {
    while read -p 'Continue? yes/no: ' input; do    
        case $input in
            [yY]*)
                echo 'Continuing'
                return
                ;;
            [nN]*)
                break
                ;;
             *)
                echo 'Invalid input' >&2
        esac
    done

    echo 'Ok, exiting'
    exit 1
}

Here, there are three ways out of the loop:

  1. The user enters "yes", in which case the function returns.
  2. The user enters "no", in which case the we break out of the loop and execute exit 1.
  3. The read fails due to something like encountering an end-of-input or some other error, in which case the exit 1 is executed.

Instead of exit 1 you may want to use return 1 to allow tho caller to decide what to do when the user does not want to continue. The calling code may then look like

if ! ask_continue; then
    # some cleanup, then exit
fi

Solution 2

Why not just repeating the read?

unset i
while [[ ! "$i" =~ ^[yYnN]$ ]]; do read -r -p "Would you like to continue  [Y/N] : " i; done

Solution 3

You can do by keeping switch case inside a function.

function testCase ()
{
    read -r -p "Would you like to continue  [Y/N] : " i
    case $i in
        [yY])
            echo -e "Resuming the script";;
        [nN])
            echo -e "Skipped and exit script"
            exit 1;;
        *)
            echo "Invalid Option"
            testCase
            ;;
    esac
}
testCase

If the input is invalid it will recall the function until it gets a valid input.

Solution 4

until [ "$i" = "0" ]
do
read -r -p "Would you like to continue  [Y/N] : " i
case $i in
        [yY])
                echo -e "Resuming the script";;
        [nN])
                echo -e "Skipped and exit script"
                exit 1;;
        *)
                echo "Invalid Option"
                ;;
esac
done
Share:
10,397
Admin
Author by

Admin

Updated on September 18, 2022

Comments

  • Admin
    Admin over 1 year

    I have the following code in the middle of a script to confirm whether we want to resume the script or not.

    read -r -p "Would you like to continue  [Y/N] : " i
    case $i in
            [yY])
                    echo -e "Resuming the script";;
            [nN])
                    echo -e "Skipped and exit script"
                    exit 1;;
            *)
                    echo "Invalid Option"
                    ;;
    esac
    

    I would like to know is there any way to know is there any way to recall the switch-case if the input option is invalid?

  • Kusalananda
    Kusalananda over 5 years
    Or until you run into a resource restriction or a maximum recursion depth limit.
  • ilkkachu
    ilkkachu over 5 years
    I wouldn't count on the shell being able to optimize the tail recursion, and given the usual procedural nature of shell scripts, I'd really suggest writing that loop out.
  • Barmar
    Barmar over 5 years
    @Kusalananda If the user gives an incorrect answer to a simple yes/no question so many times you hit the recursion limit, he deserves to have the script crash.
  • Stéphane Chazelas
    Stéphane Chazelas over 5 years
    You may also want to exit the script upon empty input (EOF).
  • Kusalananda
    Kusalananda over 5 years
    @StéphaneChazelas Yes, definitely. I'll update in the morning. Thanks.
  • forest
    forest over 5 years
    @Barmar A programmer should expect that the user will input anything, whether it's an incorrect answer enough times to hit a recursion limit, or eight gigabytes of null and control codes. Failing on a corner case like this is indicative of bad programming.