Bash函数参数验证

时间:2013-03-10 06:36:01

标签: bash

我有一个Bash函数f,它将字符串值s作为其参数之一。

如果s不是[1000-9999]之间的整数,我需要中止执行。

我最初认为我会尝试将字符串转换为int并对结果执行算术范围检查,中止错误,但所有其他参数都使用RegEx检查,因此我可能也是一致的。实际上我必须这样做。

Bash版本:4 +

我无法想出一个比这更好看的模式:

[[ "$s" =~ [[:\<:]][[:digit:]]{4}[[:\>:]] ]]

你能帮助我提高上面模式检查结构的可读性吗?

我在上面的模式中特别不喜欢的是:

  • 必须反斜杠将单词边界字符<转义为[[:\<:]]
  • 它的绝对长度,以及方括号的疯狂数量

我的一个想法是使用全线边界检查,虽然这是一个黑客攻击? (即使用^ ... $而不是\ b ... \ b)


(可选) :: Bash中的参数验证是否有相当完善的模式?

3 个答案:

答案 0 :(得分:2)

另外,我会尝试:

[[ $s =~ ^[1-9][0-9]{3}$ ]]

否则0999会通过。但另一方面可能是+1234可能是有效输入,因此可能是1234.0,所以如果你需要完成,你可能需要扩展你的正则表达式,或者毕竟执行值检查..

答案 1 :(得分:2)

bash可以进行整数比较:

shopt -s extglob # Needed for the extended pattern +(...)
f () {
    if [[ $1 == +([[:digit:]]) ]] &&
       (( $1 >= 1000 && $1 < 10000 )); then
    ...
    fi
}

答案 2 :(得分:1)

请参阅http://mywiki.wooledge.org/BashFAQ/054

你可以只使用模式匹配来做到这一点,但我会拆分它。我会说这样的事情接近于“通常”的方法:

f() {
    if [[
        $1 == +([[:digit:]]) &&
        "$1 >= 1000 && $1 < 10000" -ne 0
        ]]
    then
        ...
    fi
}

在Bash / ksh测试表达式复合命令中,数值比较运算符的参数被计算为算术表达式。双引号允许表达式中的空格,否则解析器无法区分某些算术运算符和测试表达式运算符。测试左侧的表达式0是否基本等同于(())。除了只使用一个命令外,这与@ chepner的answer完全相同。我希望这表现得稍好一些,我习惯了语法,所以我很清楚。有些人更喜欢另一种方式。与其他测试结合使用时,您应该只使用[[算术运算符而不是((

在使用任何不可预测的输入作为算术表达式之前,您必须首先进行验证。然后你可以检查它是否在一定范围内。还有其他方法可以做到这一点,但这就是我个人的方式。它很清楚,适用于这个问题的所有排列。

我还应该补充一点,如果您的输入可能包含八进制或十六进制文字,则需要进行一些进一步的处理。在这种情况下,通常通过printf %d运行输入效果很好。