9

I wrote a bash script which takes numbers for calculation via user input. The problem I have is if the user types a letter or a space by mistake, the whole script fails and the user must start again.

There must be an easy way to check the input is numeric only that will ask for the input again if anything else is input accidentally?

codeforester
  • 39,467
  • 16
  • 112
  • 140

3 Answers3

20

Use a while loop

number=""
while [[ ! $number =~ ^[0-9]+$ ]]; do
    echo Please enter your age
    read number
done
echo You are $number years old
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Yes that works, thanks, but im re-using the same Variable so next time it comes round it has a value from the last entry. any ideas? –  May 11 '09 at 14:43
  • 1
    i don't quite understand what you mean. That's why we set it to an empty string before we enter the loop :) – Johannes Schaub - litb May 11 '09 at 15:03
  • 1
    The solution above still accepts input like '22aa', 'aa 22', or 'a23bb'. The regexp should include the start and the end of the string: while [[ ! ($number =~ ^[0-9]+$) ]]; do – Fritz G. Mehner May 12 '09 at 06:42
  • Thanks litb while [[ ! ($number =~ ^[0-9]+$) ]]; do thats what i was after much appreciated danke –  May 14 '09 at 12:39
8

And to avoid the heavy regex engine, use a simple glob:

if [[ ! $input || $input = *[^0-9]* ]]; then
    echo "Error: '$input' is not a number." >&2
fi
lhunath
  • 120,288
  • 16
  • 68
  • 77
5

Allows space before and after the number, _33, or 33___ , but not 3__3. and no letters. 0 or

-- Get input from user until Correct

    # -- get input until Correct
    unset get_num
    while [[ ! ${get_num} =~ ^[0-9]+$ ]]; do
        echo "Please enter in a number:"
        read get_num
    done
    echo This is a number :  ${get_num}

-- Get input until Correct (within range)

    # -- get input until Correct (within range)
    unset get_num
    while [[ ! ${get_num} =~ ^[0-9]+$ ]]; do
        echo "Please enter in a number within range of (1-30):"
        read get_num
        ! [[ ${get_num} -ge 1 && ${get_num} -le 30  ]] && unset get_num
    done
    echo This is a number withn a range :  ${get_num}

-- get input until Correct (within range) (full regex way)

"Since regular expressions deal with text rather than with numbers, matching a number in a given range takes a little extra care. You can't just write [0-255] to match a number between 0 and 255. Though a valid regex, it matches something entirely different. [0-255] is a character class with three elements: the character range 0-2, the character 5 and the character 5 (again). This character class matches a single digit 0, 1, 2 or 5, just like [0125]." ~ http://www.regular-expressions.info/numericranges.html

    # -- get input until Correct (within range) (another way)
    unset get_num
    while [[ ! ${get_num} =~ ^([1-9]|1[0-9]|2[0-9]|30)$ ]]; do
        echo "Please enter in a number within range of (1-30):"
        read get_num
    done
    echo This is a number withn a range :  ${get_num}

-- Get input, and check it only (no while loop)

    # -- get input, and check it only (no while loop)
    unset get_num
    echo "Please enter in a number:"
    read get_num
    if [[ ! ${get_num} =~ ^[0-9]+$ ]] ;then 
        echo "${get_num} isn't a number" 
    else
        echo "${get_num} is a number"
    fi
Mike Q
  • 6,716
  • 5
  • 55
  • 62