Command line user input validation

Hi guys, I have a piece of snippet below which asks the user to input some numbers

    if isDatasubEnabled && isReconEnabled; then
        echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
    
    elif isDatasubEnabled && isReconEnabled=0; then
        echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"

    elif isDatasubEnabled=0 && isReconEnabled; then
        echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
        
    else
        echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"
    fi

read daemonOption

i=1

if [ "$daemonOption" = '7' ] ; then
   return
fi

if [ "$daemonOption" = "" ] ; then
   echo "Error..."
   stop_daemons;
   return
else
   daemonLength=`expr length $daemonOption`
   while [ "$i" -lt $daemonLength+1 ]
   do
      substring=`expr substr $daemonOption $i 1`
      if [ "$substring" != '1' ] && [ "$substring" != '2' ] && [ "$substring" != '3' ] && [ "$substring" != '4' ] && [ "$substring" != '5' ] && [ "$substring" != '6' ]
      then
         echo "Error..."
         stop_daemons;
         return
      fi
   let i++
   done
fi

The problem with the above is for example:

if datasub and recon are both off, then the user will see the following
echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"

But the user can still enter the number 2 or 5, which is not right

I need some way of only allowing the user to enter the numbers that are on the menu, any ideas guys?

Have you tried using "case" statement?

read daemonOption

case "${daemonOption}" in
     "value 1" | "value 11") <do something>;;
     "value 2") <do something>;;
     "value n") <do something>;;
     *) echo "Invalid value.";;
esac

# Example
a=10
case "$a" in
	"1" | "11") echo 1;;
	"2") echo 2;; 
	"10") echo 10;;
	*) echo "Invalid value"
esac

Also, if you want only numbers, you can use:

# ...
read daemonOption

expr ${daemonOption} + 1 1>/dev/null 2>&1
exprRetCode=${?}

if [ ${exprRetCode} -ne 0 ]
then
       echo "WARN: Only number allowed."
fi

Regards!

Many thanks for the reply felipe. But is there a way to set the validation when the options are echo'd, for example:

    if isDatasubEnabled && isReconEnabled; then
        echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
        allowedInput = "1234567";
    
    elif isDatasubEnabled && isReconEnabled=0; then
        echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"
        allowedInput = "123467";

    elif isDatasubEnabled=0 && isReconEnabled; then
        echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
        allowedInput = "13457";
        
    else
        echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"
        allowedInput = "13467";
    fi

and then somehow used this allowedInput variable in the 2nd part of the code to validate the input? Because what the code will eventually do at the end is send the daemonOption to a oracle procedure

The full function:

function stop_daemons {
echo "Stop Daemons - Please enter one or a combination of the following:"

	if isDatasubEnabled && isReconEnabled; then
		echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
	
	elif isDatasubEnabled && isReconEnabled=0; then
		echo "1 = CGT, 2 = Subscriber, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"

	elif isDatasubEnabled=0 && isReconEnabled; then
		echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 5 = Reconciliation, 6 = All, 7 = Exit"
		
	else
		echo "1 = CGT, 3 = Order Monitor, 4 = Revaluations, 6 = All, 7 = Exit"
	fi

read daemonOption

i=1

if [ "$daemonOption" = '7' ] ; then
   return
fi

if [ "$daemonOption" = "" ] ; then
   echo "Error..."
   stop_daemons;
   return
else
   daemonLength=`expr length $daemonOption`
   while [ "$i" -lt $daemonLength+1 ]
   do
      substring=`expr substr $daemonOption $i 1`
      if [ "$substring" != '1' ] && [ "$substring" != '2' ] && [ "$substring" != '3' ] && [ "$substring" != '4' ] && [ "$substring" != '5' ] && [ "$substring" != '6' ]
      then
         echo "Error..."
         stop_daemons;
         return
      fi
   let i++
   done
fi

  sqlplus -S / <<EOF

BEGIN
  pfs245p.stop_daemons('$daemonOption');
END;
/

EOF

  daemons
}

Check below, it may help you!

#!/bin/bash

isNumber ()
{
	# Validates if argument is a number or not
	# return/echo the argument if it is a number 
	# return -1 if it is not a number
	errRetCode="-1"
	
	var="${1}"
	
	# expr exit status:
	#	0 if the expression is neither null nor 0,
	#	1 if the expression is null or 0,
	#	2 if the expression is syntactically invalid,
	#	3 if an error occurred.
	var=`expr ${var} + 0 2>/dev/null`
	[ ${?} -gt 1 ] && var=${errRetCode}
	echo ${var}
	return ${var}
}

validateOpt ()
{
	# Validates a input value against a list of values
	# returns 0 if is a valid opt
	# returns 1 if it is a 
	inputOpt="${1}"
	allInputOpt="${2}"
	
	errRetCode="-1"
	
	nInputOpt=`isNumber "${inputOpt}"`
	if [ ${nInputOpt} -eq -1 ]
	then
		echo "ERROR: Invalid number: [${inputOpt}]."
		return ${errRetCode}
	fi
	
	for validOpt in ${allInputOpt}
	do
		if [ ${nInputOpt} -eq ${validOpt} ]
		then
			echo "INFO: Option is valid: [${inputOpt}]."
			return 0
		fi
	done
	
	echo "ERROR: Invalid option: [${inputOpt}]."
	return ${errRetCode}
}

# Some Tests

validateOpt "1" "1 2 4 5 10"
validateOpt "10" "1 2 4 5 10"
validateOpt "-1" "1 2 4 5 10"
validateOpt "a" "1 2 4 5 10"

validateOpt "1" "1 2 4 5 10"
if [ ${?} -ne 0 ]
then
	# Either user entered an invalid number or an invalid option
fi

Regards.

Thanks alot for this felipe - it looks like it is exactly what I need. I will combine this function with my stuff and post back!