两个整数之间的Bash值,NOT浮点



我有一个简单的比较运算符,它检查number是否在1和3之间(也包括1和3(。但如果我将number分配给3,2,它仍然接受为正确的。

它应该只接受那些值1-2-3

我的代码

if (("$number" >= 1 && "$number" <= 3)); then
echo 'Correct number'
fi

(("$number" >= 1 && "$number" <= 3))是Bash的独立算术表达式。

在算术表达式中,变量按原样展开,如果它们包含有效算术表达式的语法元素,也会对其进行解释。

number="3,2"在算术表达式中扩展为((3,2)),其中逗号,被Bash的算术表达式解释为语句分隔符。

让我们看看:

$ number="3,2"; echo "$((number))"
2
$ number="3+2"; echo "$((number))"
5
$ number="3*2"; echo "$((number))"
6

shell只理解整数运算,但3,2不是有效的整数值。

这意味着,如果您不确定变量是否包含有效整数,则在算术表达式中使用该变量是不安全的。

在算术表达式或比较整数的测试中使用之前,请始终检查number是否包含有效整数(请参阅:测试字符串是否为有效整数(。

# Check number is a valid integer before testing its range.
[[ $number =~ ^[-+]?[0-9]+$ ]] && (("$number" >= 1 && "$number" <= 3))

其他答案中建议的其他数字测试方法[ "$number" -ge 1 ] && [ "$number" -le 3 ]将错误为:bash: [: 3,2: integer expression expected

它还需要测试有效整数:

[[ $number =~ ^[-+]?[0-9]+$ ]] && [ "$number" -ge 1 ] && [ "$number" -le 3 ]

对于POSIXshell,没有Regex测试,因此需要一种不同的方法:

case "${number#[+-]}" in(*[!0123456789]*|'')false;;esac &&
[ "$number" -ge 1 ] && [ "$number" -le 3 ]

关于使用算术表达式比较数字的陷阱的附加说明。算术表达式将处理整数的前导0,作为八进制:

$ (( 13 >= 12 )); echo $?
0

但是

$ (( 013 >= 12 )); echo $?
1

试试这个:

if [ "$number" -ge 1 ] && [ "$number" -le 3 ]; then 
echo 'Correct number'
fi

您必须按照如下方式重写代码:

if [ "$number" -ge 1 ] && [ "$number" -le 3 ]; then
echo 'Correct number'
fi

看看https://tldp.org/LDP/abs/html/comparison-ops.html以获取更多信息。

最新更新