Linux Shell 脚本:针对 if 语句计算输入字符,但不符合预期

Linux Shell 脚本:针对 if 语句计算输入字符,但不符合预期

我有一个包含一些元素的数组,并且在某些函数中包含以下内容:

echo -n "Select the option: "
read option

echo "option: '${option}'"
echo "option: '$option'"

if [[ $option -ge 1 && option -le ${#array[@]} ]]; then
 echo "go go go"
 ...
else
 ...
fi

关于输入 - 如果写入的数字高于数组的长度/大小,则该else块将按预期执行 - 与负数相同 - 或什至0。到这里一切都在预料之中

但如果写入一个简单的字符,如s,则执行该块,并且它是dif不是预期的。

select the option: d
option: 'd'
option: 'd'
go go go

根据我的理解-ge,它-le应用于数字 - 所以如果使用字符如何进行数字比较,它应该失败 - 它应该直接进入else

如何解决这个问题?

答案1

这里发生的事情(对你来说)是一个意想不到的评价。作为参考,这是您的原始表达

[[ $option -ge 1 && option -le ${#array[@]} ]]

首先,$option进行评估。在本例中是d.然后将其代入[[ … ]]表达式以获得:

[[ d -ge 1 && option -le 12 ]]

这是评价的。但是因为[[ … ]]使用bash的表达式求值doption被视为变量的名称,所以还有另一个级别的扩展(隐式地意识到这一点d=0):

[[ 0 -gt 1 && d -le 12 ]]

第一部分失败,因此跳过第二个(错误的)表达式。

您可以考虑以下几种解决方案:

  1. 而不是使用[[ … ]]旧的但可以接受的[ … ]。这不会执行这种双重扩展。但是,当不是数字时,这不会捕获“非数字”错误$option,因此您仍然会收到错误

    [ "$option" -ge 1 ] && [ "$option" -le ${#array[@]} ]
    
  2. 通过验证字符串中的字符仅为数字来保护表达式比较。

    [[ "$option" =~ ^(0|([1-9][0-9]*))$ && "$option" -ge 1 && "$option" -le "${#array[@]}" ]]
    

相关内容