0

I have a pizza builder code. It gives the user to chose a pizza size and a list of toppings from a side file. I'm trying to validate users input so it can enter a number between 1 and the amount of toppings from the side file.

I'm getting the number of rows from the file and set it to a variable using wc numtop=$( cat Toppings | wc -l );

After that I read the users input and run a check using if

read topp
if [[ "$topp" < 1 || "$topp" > "$numtop" ]]; then
     echo "Enter from 1 to " $numtop
else
     echo "Good choice"
fi

But it allows me to enter only 1 or the number from my $numtop variable. I can't understand why this doesn't work.

Pashunel
  • 1
  • 1

1 Answers1

1

You need to use the (( )) for arithmetic expression, something like:

#!/usr/bin/env bash

numtop="$(wc -l < Toppings)"

while read -rp "Enter from 1 to  $numtop " topp; do
  if (( topp < 1 || topp > numtop )); then
    echo "Enter from 1 to $numtop"
  else
    echo "Good choice"
    break
  fi
done

EDIT: as per @jhnc, Given the input is something like: a[$(date>/dev/tty)],1 (the first answer breaks badly) check the value of input first if it is strictly numeric.

#!/usr/bin/env bash

##: Test also if Toppings is empty if it is a file
##: or just test the value of $numtop.
numtop="$(wc -l < Toppings)"

while printf 'Enter from 1 to %s ' "$numtop"; do
  read -r topp
  case $topp in
    ('')
      printf 'input is empty\n' >&2
       ;;
    (*[!0123456789]*)
       printf '%s has a non-digit somewhere in it\n' "$topp" >&2
       ;;
    (*)
      if (( topp < 1 || topp > numtop )); then
        printf 'You entered %s\n' "$topp"  >&2
      else
        printf 'You entered %s Good choice!\n' "$topp" &&
        break
      fi
     ;;
  esac
done

Jetchisel
  • 7,493
  • 2
  • 19
  • 18
  • 2
    you should check for non-digits first. consider if user enters: `a[$(date>/dev/tty)],1` – jhnc Jun 18 '23 at 10:19