在不干扰无效选项的情况下检测负数(以 - 开头)

Detecting negative numbers without interfering with invalid options (starting with -)

我有一个 bash 函数来验证数值(正数和负数,包括整数、浮点数和科学记数法)。

使用参数解析循环,我还想处理无效选项(从 - 开始,但会干扰用户提供的负数)。

 while (( $# > 0 )); do
    opt=""
    case $opt in
     ("-I")   fm="I"  ; shift 1 ;;  # integers
     ("-F")   fm="F"  ; shift 1 ;;  # floating point
     ("-E")   fm="E"  ; shift 1 ;;  # exponential notation
     ("--")  shift 1 ; break ;;
     # ----------------------------
     ("-"*)  status=64 ; shift 1 ;;
     # ----------------------------
     (*) break ;;
     # ----------------------------
    esac  # case ends here
  done  # while ends here
  

对于用户调用的情况,我已经将 -- 检测为选项结束的指示符。但是当从另一个函数调用函数时,我无法事先知道该值是正数还是负数。

如何检测参数是否包含会使参数无效的字符?然后我可以在"-"*部分引入检查。

您可以测试模式 ("-"[0-9]*),然后假设(此时)甚至 -5X 也是一个数字。好吧,这也不是一个有效的选项,如果您稍后对数字参数进行有效性检查,您无论如何都会发现这种情况。

如果我们只关注整数,另一种方法是显式测试错误情况:模式 -*[!0-9]* 匹配以连字符开头并在后面包含某些内容 non-numeric 的参数,如果此模式匹配,您知道您有一个非法选项而不是数字。

在你的情况下,第一种方法似乎更明智,因为你似乎也允许小数。因此,什么是有效数字取决于之前设置的选项(-I-F),无论如何您都必须根据您期望的数字类型进行验证。为了验证指数格式,我会进行正则表达式匹配,而不是 glob 模式 - 取决于您允许的指数格式类型:

if [[ $opt =~ ^[-+]?[0-9]+([.][0-9]+)?E[-+]?[0-9]+$ ]]
then
  # We have a valid number in exponential notation
  ...

当然,要使用的确切模式取决于指数表示法中允许的变化。

除此之外,您的程序仍然存在问题,因为您允许将 -I-E 都传递给您的命令。在您当前的实现中,最后一个被使用,而前一个被默默地忽略。相反,我会重新考虑您的程序设计,因为可能只提供一个选项(-I、-E 或 -F)。这必须是第一个选项,第二个参数之后的所有内容都必须是数字。