Getting Yes or No Input

Problem

You need to get a simple yes or no input from the user, and you want to be as user-friendly as possible. In particular, you do not want to be case sensitive, and you want to provide a useful default if the user presses the Enter key.

Solution

If the actions to take are simple, use this self-contained function:

# cookbook filename: func_choose

# Let the user make a choice about something and execute code based on
# the answer
# Called like: choose <default (y or n)> <prompt> <yes action> <no action>
# e.g. choose "y" 
#       "Do you want to play a game?" 
#       /usr/games/GlobalThermonucularWar 
#       'printf "%b" "See you later Professor Falkin.
"' >&2
# Returns: nothing
function choose {

    local default="$1"
    local prompt="$2"
    local choice_yes="$3"
    local choice_no="$4"
    local answer

    read -p "$prompt" answer
    [ -z "$answer" ] && answer="$default"

    case "$answer" in
        [yY1] ) eval "$choice_yes"
            # error check
            ;;
        [nN0] ) eval "$choice_no"
            # error check
            ;;
        *     ) printf "%b" "Unexpected answer '$answer'!" >&2 ;;
    esac
} # end of function choose

If the actions are complicated, use this function and handle the results in your main code.

# cookbook filename: func_choice.1

# Let the user make a choice about something and return a standardized
# answer. How the default is handled and what happens next is up to
# the if/then after the choice in main
# Called like: choice <promtp>
# e.g. choice "Do you want to play a game?"
# Returns: global variable CHOICE
function choice {

    CHOICE=''
    local prompt="$*"
    local answer

    read -p "$prompt" answer
    case "$answer" in
        [yY1] ) CHOICE='y';;
        [nN0] ) CHOICE='n';;
        *     ) CHOICE="$answer";;
    esac
} # end of function choice

The following code calls the choice function to prompt for and verify a package date. Assuming $THISPACKAGE is set, the function displays the date and asks for verification. If the user types y, Y, or Enter, then that date is accepted. If the user enters a new date, the function loops and verifies it (for a different treatment of this problem, see Figuring Out Date and Time Arithmetic):

# cookbook filename: func_choice.2
CHOICE=''
until [ "$CHOICE" = "y" ]; do
    printf "%b" "This package's date is $THISPACKAGE
" >&2
    choice "Is that correct? [Y/,<New date>]: "
    if [ -z "$CHOICE" ]; then
        CHOICE='y'
    elif [ "$CHOICE" != "y" ]; then
        printf "%b" "Overriding $THISPACKAGE with ${CHOICE}
"
        THISPACKAGE=$CHOICE
    fi
done

# Build the package here

Next we’ll show different ways to handle some “yes or no” questions. Carefully read the prompts and look at the defaults. In both cases the user can simply hit the Enter key, and the script will then take the default the programmer intended.

# If the user types anything except a case insensitive 'n', they will
# see the error log
choice "Do you want to look at the error log file? [Y/n]: "
if [ "$choice" != "n" ]; then
    less error.log
fi

# If the user types anything except a case insensitive 'y', they will
# not see the message log
choice "Do you want to look at the message log file? [y/N]: "
if [ "$choice" = "y" ]; then
    less message.log
fi

Finally, this function asks for input that might not exist:

# cookbook filename: func_choice.3

choice "Enter your favorite color, if you have one: "
if [ -n "$CHOICE" ]; then
    printf "%b" "You chose: $CHOICE
"
else
    printf "%b" "You do not have a favorite color.
"
fi

Discussion

Asking the user to make a decision is often necessary in scripting. For getting arbitrary input, see Getting User Input. For choosing an option from a list, see Selecting from a List of Options.

If the possible choices and the code to handle them are fairly straightforward, the first self-contained function is easier to use, but it’s not always flexible enough. The second function is flexible at the expense of having to do more in the main code.

Note that we’ve sent the user prompts to STDERR so that the main script output on STDOUT may be redirected without the prompts cluttering it up.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.138.144