Reputation: 81
I have this simple comparison operator, it check if number
is between 1 and 3 (1 and 3 included too). But if I assign number
to 3,2
it still accepts as correct.
It should only accept those values 1-2-3
My code
if (("$number" >= 1 && "$number" <= 3)); then
echo 'Correct number'
fi
Upvotes: 2
Views: 325
Reputation: 19615
(("$number" >= 1 && "$number" <= 3))
is a Bash's stand-alone arithmetic expression.
Within an arithmetic expression, variables are expanded as-is and if they contain valid arithmetic expression's syntax elements, these are also interpreted.
number="3,2"
expands as ((3,2))
in an arithmetic expression, where comma ,
is interpreted as a statements separator by Bash's arithmetic expressions.
Lets see:
$ number="3,2"; echo "$((number))"
2
$ number="3+2"; echo "$((number))"
5
$ number="3*2"; echo "$((number))"
6
The shell only understands integer arithmetic, but 3,2
is not a valid integer value.
It means that if you are unsure a variable contains a valid integer, it is unsafe for use within an arithmetic expression.
Always check that number
contains a valid integer (see: Test whether string is a valid integer) before using in an arithmetic expression or within a test comparing integers.
# Check number is a valid integer before testing its range.
[[ $number =~ ^[-+]?[0-9]+$ ]] && (("$number" >= 1 && "$number" <= 3))
The other numeric test method [ "$number" -ge 1 ] && [ "$number" -le 3 ]
as suggested in the other answers will error-out with: bash: [: 3,2: integer expression expected
.
It also needs testing for valid integer:
[[ $number =~ ^[-+]?[0-9]+$ ]] && [ "$number" -ge 1 ] && [ "$number" -le 3 ]
With POSIX shell, there is no Regex test, so a different approach is needed:
case "${number#[+-]}" in(*[!0123456789]*|'')false;;esac &&
[ "$number" -ge 1 ] && [ "$number" -le 3 ]
An additional note about the pitfalls of using arithmetic expressions to compare numbers. Arithmetic expressions will handle leading 0 of an integer, as an octal:
$ (( 13 >= 12 )); echo $?
0
but
$ (( 013 >= 12 )); echo $?
1
Upvotes: 6
Reputation: 5277
Try this:
if [ "$number" -ge 1 ] && [ "$number" -le 3 ]; then
echo 'Correct number'
fi
Upvotes: 5
Reputation: 11030
You have to rewrite your code as follow:
if [ "$number" -ge 1 ] && [ "$number" -le 3 ]; then
echo 'Correct number'
fi
Look at https://tldp.org/LDP/abs/html/comparison-ops.html for further information.
Upvotes: 4