Bash 避免将选项自动作为参数

Bash 避免将选项自动作为参数,bash,Bash,我想对我正在编写的bash脚本进行一些错误检查。特别是,我希望确保以下选项不被视为(故意)留空选项的参数 让我们说下面的片段 while getopts “hhelpc1:2:” OPTION do case "$OPTION" in h|help) usage exit 1 ;; 1) var1=${OPTARG} ;;

我想对我正在编写的bash脚本进行一些错误检查。特别是,我希望确保以下选项不被视为(故意)留空选项的参数

让我们说下面的片段

while getopts “hhelpc1:2:” OPTION
do
     case "$OPTION" in
         h|help)
             usage
             exit 1
             ;;
         1)
             var1=${OPTARG}
             ;;
         2)
             var2=${OPTARG}
             ;;
         c)
             test1
             ;;
     esac
done
假设我的脚本名为test.sh

通过这样做

./test.sh -1 -2 dddd -c
在上述情况下,test1输出一条错误消息,指出-2选项为空。相反,我想警告-1为空,而目前-2将作为-1的参数

有什么帮助吗

谢谢 安德里亚

getopts

  • 只处理较短的选项名称,因此不能在选项字符串中输入“help”——这意味着您正在查找“-h”、“-e”、“-l”、“-p”
  • 不能像你希望的那样寻找遗漏的论点。您必须检查$OPTARG以检查它是否像您的选项之一
  • 在opt字符串中添加一个前导的
    ,以便自己处理getopts错误

    这是对你的代码的修改,我相信有很多情况我没有抓住

    #!/bin/bash
    
    usage () { echo usage ...; }
    test1 () { echo test1; }
    
    shopt -s extglob
    
    while getopts ":hc1:2:" opt
    do
         case $opt in
             h)
                 usage
                 exit 1
                 ;;
             1)
                 case $OPTARG in
                     -[hc2]*)
                        echo "error: required argument missing for -1"
                        usage
                        exit 1
                        ;;
                     *) var1=$OPTARG
                        ;;
                 esac
                 ;;
             2)
                 case $OPTARG in
                     -[hc1]*)
                        echo "error: required argument missing for -2"
                        usage
                        exit 1
                        ;;
                     *) var2=$OPTARG
                        ;;
                 esac
                 ;;
             c)
                 test1
                 ;;
             :) 
                 echo "error: required argument missing for -$OPTARG"
                 usage
                 exit 1
                 ;;
             \?)
                 # unknown argument, handle accordingly
                 ;;
         esac
    done
    shift $((OPTIND - 1))
    
    echo "var1=$var1"
    echo "var2=$var2"
    echo "rest=$*"
    

    更新2014-01-23

    这里有一个技巧:

    do_test1=false
    
    while getopts ...
        case $opt in
            ...
            c) do_test1=true ;;
            ...
        esac
    done
    shift $((OPTIND - 1))
    
    # execute function "test1" if "-c" was given:
    $do_test1 && test1
    

    嗨,格伦。你太棒了。谢谢这段代码。我会复习的。我立即发现的是选项1的情况-[hc1]。这不应该是-[hc2]。如果不是,那我就没道理了。嗨,格伦,还有一个问题。在执行函数位之前,有没有办法解析所有参数?在上面的例子中,假设我有一个./script.sh-c-1 aa-2 bb,将-c作为第一个参数将在读取该行的所有其余部分之前触发测试函数。当然,如果参数丢失,测试可以阻止执行,但一旦读取了-1和-2,情况就不再是这样了。这里有什么提示吗?逻辑测试在case语句之外;因此,通过将do_test1设置为true,case语句将继续解析参数,如果do_test1设置为true,则在结束时,&&将执行脚本。通过这种方式,我可以引入a-t(或其他任何东西)来运行第二个函数。我还可以防止更多的函数在同一周期内运行,只要在每个函数的末尾添加一个退出位,尽管我不能保证顺序。但我想我现在有比我需要的更多的东西。谢谢。