'Confirming Shell Script Input

I'm writing a script to preform a repetitive task that only changes basic values and locations such as user name.

I've written up code that prompts for a username and verifies that it is not already in use. I'm now trying to prompt the user if the input the script received is correct and if it is not to change it. My issue is that if the input is correct it keeps looping. Anyone have any suggestions?

clear
confirm () {
    # call with a prompt string or use a default
    echo "CMIT # ${1}"
    read -r -p "CMIT [Y/n/q] > " answer
    case "${answer}" in
        [yY]|[yY][eE][sS]) false ;;
        [nN]|[nN][oO]) true ;;
        [qQ]|[qQ][uU][iI][tT]) exit 1 ;;
    esac
}

while true;  do
    OE_USER=
    while (id -u $OE_USER > /dev/null 2>&1); do
        echo "CMIT # What user will this run under?"
        read -r -p "CMIT > " OE_USER
        if id -u $OE_USER > /dev/null 2>&1; then
            echo "CMIT # Bad User Name. Try Again"
        fi
    done
    clear
    confirm "Continue installing using '$OE_USER' as the server name?"
done


Solution 1:[1]

You can either declare a global flag that gets set inside the confirm function on a good answer, or you can use a return statement inside confirm that gets tested in a conditional in your while loop.

There are other options too, like using a recursive call after testing the user input. This would negate the need for the while loop, but create the need to make your initial input a function as well.

Solution 2:[2]

You can use the exit status of your function:

Change the "yes" case to execute "true", and the "no" case to execute "false". Then

while true; do
    # ...
    if confirm "Continue installing using '$OE_USER' as the server name?" 
    then
        break
    fi
done

Solution 3:[3]

clear
GO=true
confirm () {
    # call with a prompt string or use a default
    echo "CMIT # ${1}"
    read -r -p "CMIT [Y/n/q] > " answer
    case "${answer}" in
        [yY]|[yY][eE][sS]) GO=false ;;
        [nN]|[nN][oO]) GO=true ;;
        [qQ]|[qQ][uU][iI][tT]) exit 1 ;;
    esac
}

while $GO;  do
    OE_USER=
    while (id -u $OE_USER > /dev/null 2>&1); do
        echo "CMIT # What user will this run under?"
        read -r -p "CMIT > " OE_USER
        if id -u $OE_USER > /dev/null 2>&1; then
            echo "CMIT # Bad User Name. Try Again"
        fi
    done
    clear
    confirm "Continue installing using '$OE_USER' as the server name?"
done
GO=true

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 usr242
Solution 2 glenn jackman
Solution 3 vinzee