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.
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
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.
3.138.138.144