Newer
Older
tpromptuser / tpromptuser.sh
#!/bin/sh 
# tpromptuser.sh - User Prompting From Shell With validation
# Copyright (c) 2010, TundraWare Inc, Des Plaines, IL USA
# All Rights Reserved
# $Id: tpromptuser.sh,v 1.109 2012/06/05 19:28:05 tundra Exp $

#####
# You are hereby granted a non-exclusive license to do whatever you
# like with this software so long as you understand this is
# *EXPERMENTAL SOFTWARE* that has not been thoroughly tested.  It may
# cause harm to your systems, data, and/or network.  It may compromise
# your security.  It may cause other, unspecified, kinds of harm to
# your IT environment or business.  In other words: 
#
#               USE THIS AT YOUR  OWN RISK!!!!!!
#####


#####
# What This Does
#####

# 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

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

#####
# PromptUser() - Shell Function To Prompt And Validate User Input
#####

PromptUser()

{

  for x in $PROMPTLIST
  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
            printf "Invalid Response! Must Be One Of: $answers\n"
          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 'PromptUser()'



# ---------- End Of Code ---------- #




#####
# Example
#####

# 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"


PROMPTLIST="foo bar baz bat"

# Display the records for purposes of this example only

printf "Before: foo->$foo    bar->$bar    baz->$baz    bat->$bat\n"


# Go get the user input and validate it

PromptUser


# Dump results for sake of this example only

printf "After: foo->$foo    bar->$bar    baz->$baz    bat->$bat\n"