【问题标题】:Check if every argument is an integer in shell检查每个参数是否是shell中的整数
【发布时间】:2018-10-31 14:57:57
【问题描述】:

我一直在试图弄清楚这一点,我知道这可能非常简单,所以希望一双新的眼睛能提供帮助。我有一个我正在编写的 Bourne shell (sh) 脚本,它需要一个整数列表作为输入(以及从 1 个整数开始的数量,理想情况下我想同时采用正整数和负整数)。如果有人输入整数以外的内容,我正在尝试对这种情况进行错误检查。他们可以输入“1 2 3 4 5 a”并给出错误,因为 a 不是 int。

我有一个错误检查,没有输入有效,我有代码可以对整数列表本身进行处理,但即使给出了字符串,它仍然会到达我的最终代码块。

我目前有一个 for 循环来遍历整数列表中的每个项目,然后如果所讨论的参数不是 int,则有一个 if 循环来给出错误消息。我尝试了几个不同的版本,但这是最新的,所以我把它放在下面。

for i in $@; do 
    if [ $i -ge 0 ] 2>/dev/null; then
        echo "Invalid input: integers only."
        exit 1
    fi 
done

【问题讨论】:

    标签: shell unix integer arguments sh


    【解决方案1】:
    #!/bin/sh
    #
    
    for i in "$@"
    do 
        case "${i#[-+]}" in 
            0) 
                echo cannot be 0?
                exit 1
                ;; 
            *[!0-9]* | '')
                echo not int
                exit 2
                ;; 
        esac
    done
    
    echo i\'m ok
    

    这应该适用于正整数和负整数。如果你承认 0 是一个整数,就删除第一个 case。

    几乎重复:BASH: Test whether string is valid as an integer? 这是posix的一个很好的答案。 https://stackoverflow.com/a/18620446/7714132

    【讨论】:

    • 是的!这是第一个起作用的!谢谢!另外,您介意解释一下逻辑吗,因为这样我就完全理解了它是如何实现的?
    • 这很明显,您应该深入了解一下 bash。发出“man bash”并搜索“case”、“路径名扩展”、“删除匹配的前缀模式”等。
    【解决方案2】:

    你可以使用正则表达式:

    my_script.sh

    for i in $@ ; do 
        if ! [[ "$i" =~ ^-?[0-9]+$ ]] ; then
            echo "Invalid input: integers only."
            exit 1
        fi
    done
    

    例子:

    $ sh my_script.sh 1 2 3 4
    $ sh my_script.sh 1 2 -12
    $ sh my_script.sh 1 2 -12-2
    Invalid input: integers only.
    $ sh my_script.sh 1 2 a b
    Invalid input: integers only.
    

    正则表达式的解释:

    • ^: 字符串开头
    • -?:字符的 0 或 1 倍 -
    • [0-9]+:一位或多位数字
    • $: 字符串结束

    【讨论】:

    • 使用一个“[ ]”和两个“[[ ]]”有什么区别?我读过这两个是用于 bash,但如果这是在 bourne shell 中,它会工作吗?
    • 我也尝试了两种方式(单括号和双括号),但仍然无法正常工作:/
    • 这适用于 bash/ksh/zsh,但不适用于 ash/dash/bourne/posix
    【解决方案3】:

    在 POSIX sh 中,您可以使用 case 将字符串与 glob 匹配:

    #!/bin/sh
    for i
    do
      case "$i" in
        *[!0-9]*)
          echo "Integers only" >&2
          exit 1
      esac
    done
    echo "Ok"
    

    它是这样运行的:

    $ ./myscript 1 2 3 4 5
    Ok
    
    $ ./myscript 1 2 3 4 5 a
    Integers only
    

    您的方法的问题主要在于您检查的是成功而不是失败:当输入无效时,[ 将失败。

    【讨论】:

    • 这个单圆括号的作用是什么?
    • @MandyLB 你能说得更具体点吗?例如,“我编写了一个包含 ./myscript 1 2 3 行的脚本 mytest,但是当我运行 ./mytest 时,当我期望“Ok”时,我仍然得到“Integers only””
    • 我有一个完整的脚本,就像我在最初的帖子中所说的那样,它适用于检查 0 输入,适用于所有整数,但对非整数的错误检查不起作用。提供的关于如何修复代码的建议(在我最初的帖子中)没有奏效,它仍然会转到下一个代码块并运行整数等输入,即使检查应该停止它。永远不会给出错误说输入不是 int。
    • @MandyLB 我不明白。当你重复我的测试用例时,你会得到不同的结果吗?或者您是说测试用例运行良好,但您无法将其应用于更大的脚本?
    猜你喜欢
    • 2012-11-15
    • 2013-03-22
    • 2012-10-20
    • 2012-06-01
    • 2016-02-09
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多