Newer
Older
tpromptuser / tpromptuser.sh
#!/bin/sh 
# promptuser.sh - User Prompting From Shell With validation
# Copyright (c) 2010, TundraWare Inc, Des Plaines, IL USA
# All Rights Reserved
# $Id: tpromptuser.sh,v 1.103 2010/10/07 18:58:50 tundra Exp $

# Loop through a set of questions for the user to answer, storing
# their response back into the prompt variable itself.
#
# This is convenient way to build answers to a set of configuration
# questions at the beginning of a script.  
#
# This is cleaner than having an explicit prompt stanza for each
# variable in the script that needs to be set.
#
# Note that this uses the "eval ...\$$" rather than the more modern
# ${!var} idiom for indirect variable references.  This is for
# portability. The latter form is a bash-ism and is not supported in
# a traditional Bourne Shell.
#
# This version implements a prompt table scheme that allows the
# specification of a default response and a list of legitimate
# single character answers to the prompt.  If this list is empty,
# then any response to the prompt is accepted.


#####
# Constants
#####

# Separators

ORIGIFS=$IFS       # Save current field separator
DL=';'             # Prompt field delimiter

# Common Answers

YN="Y y N n Yes yes No no YES NO"


#####
# Prompt Records
#####

# Layout Of Fields In Prompt Record:
#
# Prompt<delim>Default Response (If user just hits Enter)<delim>Legal Answers (space separated)
# Notes:
#
#  1) An empty Prompt field means there will be no prompt displayed
#
#  2) An empty Default Response field means that, if the user hits enter,
#     the response is blank
#
#  3) An empty Legal Answers field mean the routine will accept *any* input
#
#  4) It's up to you to make sure the Default Response is a legit answer.
#     It is NOT checked against the Legal Answers list.


# Examples

foo="Would you like to foo?${DL}Y${DL}"                    # Empty last field means accept anything
bar="Would you like to bar?${DL}\!${DL}${YN}"
baz="Would you like to baz?${DL}n${DL}${YN} yup"
bat="Would you like to bat?${DL}${DL}nope"


# Display the records for purposes of this example only

echo "Before: foo->$foo    bar->$bar    baz->$baz    bat->$bat"


# ---------- Nothing Should Change Below This Line ---------- #

#####
# Actual Prompting Logic
#####


for x in "foo" "bar" "baz" "bat"
do
    eval record=\$$x     # Get the prompt record
    IFS=$DL              # Get individual fields
    read prompt default answers <<EOF
$record
EOF

    IFS=$ORIGIFS         # And restore the original field separator

    # Now read input and check it against list of valid responses
    
    DONE=False

    while [ _$DONE = _False ]
    do

      read -p "${prompt} (Default: ${default}) " ANS

      # We're done if the user took the default OR if the "Legal
      # Answers" field is empty (which means we accept anything)

      if [ _"$ANS" = _ ] || [ _"$answers" = _ ]
      then
        DONE=True

      # Otherwise, make sure answer is legit

      else
        for a in $answers      # Check against each possible legal answer
        do
          if [ _$a = _"$ANS" ]
          then
            DONE=True
          fi
        done

        if [ _$DONE = _False ]
        then
          echo "Invalid Response! Must Be One Of $answers"
        fi
      fi

    done

    # Save the answer back into the original prompt variable,
    # substituting the default value if the user entered nothing.

    ANS=${ANS:-$default}
    eval $x=\"$ANS\"

done


# End Of Prompting Logic



# Dump results for sake of this example only

echo "Before: foo->$foo    bar->$bar    baz->$baz    bat->$bat"