37

I want to just insert number between two values, and otherwise the script repeated until correct number.

This is my script and it does not work correctly:

validation(){
read number
if [ $number -ge 2 && $number -ls 5 ]; then
    echo "valid number"
    break
else
    echo "not valid number, try again"
fi

}

echo "insert number"
validation
echo "your number is" $number
codeforester
  • 39,467
  • 16
  • 112
  • 140
jack
  • 521
  • 2
  • 6
  • 9

6 Answers6

49

If you are using Bash, you are better off using the arithmetic expression, ((...)) for readability and flexibility:

if ((number >= 2 && number <= 5)); then
  # your code
fi

To read in a loop until a valid number is entered:

#!/bin/bash

while :; do
  read -p "Enter a number between 2 and 5: " number
  [[ $number =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
  if ((number >= 2 && number <= 5)); then
    echo "valid number"
    break
  else
    echo "number out of range, try again"
  fi
done

((number >= 2 && number <= 5)) can also be written as ((2 <= number <= 5)).


See also:

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • 4
    Running `bash` `4.4-5` on Debian 9.8 here. `if ((2 <= 255 <= 254)); then echo 'true'; else echo 'false'; fi` returned `true`. And `if ((2 <= 255 && 255 <= 254)); then echo 'true'; else echo 'false'; fi` returned `false`. – Fonzie Mar 07 '19 at 08:31
  • 3
    One of my colleagues said `((2 <= number <= 5))` is evaluated as `((((2 <= number)) <= 5))` and that explained it. Brace expansion order is from left to right, as seen in http://man7.org/linux/man-pages/man1/bash.1.html#EXPANSION – Fonzie Mar 07 '19 at 08:56
  • How to do this in single line, since I need it on a pipe to filter (URL) from `curl` that had year at the end of it... this is my code curl -s "$Url" -o - |awk '{print "http://web.archive.org/web/"$2"/"$1}' In short it's Archive.org `url` like this `http://web.archive.org/cdx/search/cdx?url=stackoverflow.com&fl=original,timestamp&matchType=prefix&limit=19&filter=statuscode:200&filter=mimetype:text/html` – Salem Feb 13 '23 at 12:30
  • Please ask that as a separate question, @Salem – codeforester Feb 23 '23 at 03:17
  • ^^ sorry I'm restricted from asking more questions here, anyway I'll find the answer somewhere else. – Salem Feb 23 '23 at 20:47
11

Your if statement:

if [ $number -ge 2 && $number -ls 5 ]; then 

should be:

if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then

Changes made:

  • Quoting variables is considered good practice.
  • ls is not a valid comparison operator, use le.
  • Separate single-bracket conditional expressions with &&.

Also you need a shebang in the first line of your script: #!/usr/bin/env bash

builder-7000
  • 7,131
  • 3
  • 19
  • 43
3
if [ $number -ge 2 && $number -ls 5 ]; then

should be

if [[ $number -ge 2 && $number -le 5 ]]; then

see help [[ for details

Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
1

Try bellow code

echo "Enter number" 

read input

  if [[ $input ]] && [ $input -eq $input 2>/dev/null ]

  then

        if ((input >= 1 && input <= 4)); then

    echo "Access Granted..."

    break

  else

    echo "Wrong code"

  fi

  else

     echo "$input is not an integer or not defined"

  fi
Syscall
  • 19,327
  • 10
  • 37
  • 52
Titulo
  • 17
  • 2
0

2 changes needed.

  1. Suggested by Sergio.

    if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then

  2. There is no need of break. only meaningful in a for, while, or until loop

Jayesh Dhandha
  • 1,983
  • 28
  • 50
0

while :; do read option if [[ $option -ge 1 && $option -lt 4 ]]; then echo "correct" c break else echo "Incorrect option selected,choose an option between [1-4]" fi done