Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Asking a Question

In interactive shell scripts, you need to obtain input from the user. Sometimes this involves asking simple yes or no questions. In other instances, you need to ask the user a question that requires a more complicated response. For example, many scripts need to retrieve the name of a file on which to operate.

In this section, I present two functions that help you to prompt the user and get a response:

  promptYESNO
  promptRESPONSE

Asking a Yes or No Question

One of the most common types of questions asked by shell scripts is a yes or no question. For example, this shell script

Make backup (y/n)?

asks whether you want to make a backup.

The function, promptYESNO, provides you with a reusable method of asking a yes or no question and getting a response. The user’s response, y indicating yes or n indicating no, is stored in the variable YESNO after the function completes.

################################################
# Name: promptYESNO
# Desc: ask a yes/no question
# Args: $1 -> The prompt
#       $2 -> The default answer (optional)
# Vars: YESNO -> set to the users response
#                y for yes, n for no
################################################

promptYESNO() {

    if [ $# -lt 1 ] ; then
        printERROR "Insufficient Arguments."
        return 1

    fi

    DEF_ARG=""
    YESNO=""

    case "$2" in
        [yY]|[yY][eE][sS])
            DEF_ARG=y ;;
        [nN]|[nN][oO])
            DEF_ARG=n ;;
    esac

    while :
    do

        printf "$1 (y/n)? "

        if [ -n "$DEF_ARG" ] ; then
            printf "[$DEF_ARG] "
        fi

        read YESNO

        if [ -z "$YESNO" ] ; then
            YESNO="$DEF_ARG"
        fi

        case "$YESNO" in
            [yY]|[yY][eE][sS])
                YESNO=y ; break ;;
            [nN]|[nN][oO])
                YESNO=n ; break ;;
            *)
                YESNO="" ;;
        esac

    done

    export YESNO
    unset DEF_ARG
    return 0
}

Before you look at an example of this function in use, examine how it works.

As indicated by the comments, this function can handle up to two arguments. It treats the first argument as the prompt and the second argument as the default answer to the prompt. First, this function checks that at least one argument is given. If no arguments are given, you return from the function with the error message

ERROR: Insufficient Arguments.

Next, set the variables DEF_ARG and YESNO to null, in order to avoid using the values stored in them from a previous call to this function. After this, try to set DEF_ARG, the default answer, by looking at the value of the second argument to the function, $2. If this argument is some form (regardless of case) of the words YES or NO, you set DEF_ARG; otherwise, you leave it as null.

At this point, you enter the body of an infinite while loop. You call the break command from inside the while loop after the user has entered a valid answer (some form of the words YES or NO).

The first thing the loop does is output a prompt using the printf command. You use the printf command to avoid problems with the echo command between different versions of UNIX. If a valid default answer was specified, you display it.

After the prompt is displayed, call the read command and read the user’s response into the variable YESNO. If the user simply presses Enter, YESNO is set to null. In this case, you set it equal to the default answer stored in DEF_ARG. If the default argument was not given, this assignment is redundant.

The last step in the while loop is to check the value of YESNO and make sure that it contains some form of the words YES or NO. If it does, you call the break command to terminate the while loop.

If YESNO contains an invalid response, the loop repeats. This means that if the user simply types Enter in a case where no default was supplied, or if the user enters a response that the function does not understand, the same prompt is displayed again.

Before the function exits, it exports the variable YESNO to the environment to make sure that this variable is available to commands executed after the function exits.

Now that you know how this function works, look at an example of its use, as illustrated here:

promptYESNO "Make backup"
if [ "$YESNO" = "y" ] ; then
    cp -r docs backup
fi

This generates a prompt similar to the following:

Make Backup (y/n)?

If you enter some form of the words YES or NO, the function sets the variable YESNO to either y or n. The if statement in this example evaluates this response and performs the appropriate action. Here you execute a cp command. If the user does not enter a valid response, the prompt repeats.

You can use a default argument as follows:

promptYESNO "Make backup" "y"
if [ "$YESNO" = "y" ] ; then
    cp -r docs backup
fi

Now the prompt looks like the following:

Make Backup (y/n)? [y]

This lets the user simply press Enter and have the backup made. It also lets the user type a response.


Previous Table of Contents Next