【问题标题】:getopts - if a flag is empty getopts use the next flaggetopts - 如果一个标志为空 getopts 使用下一个标志
【发布时间】:2015-12-29 09:24:03
【问题描述】:

我正在尝试将 getopts 用于 bash 脚本。这个脚本可以有标志,所有这些标志都是强制性的,需要包含一个值。当应该包含值的强制标志之一为空时,getopts 使用下一个行标志作为其内容。如何防止这种情况发生?

这是我的例子:

#!/bin/bash

while getopts "A:B:" OPTION
do
        case $OPTION in
        A)
        GILIA="$GILIA $OPTARG"
        echo GILIA $GILIA
        ;;
        B)
        GILIB="$GILIB $OPTARG"
        echo GILIB $GILIB
        ;;
        esac
done

当使用带有值的两个标志时:

./test_opt2 -A aaa -B bbb
GILIA aaa
GILIB bbb

当使用“-A”标志为空时:

./test_opt2 -A  -B bbb
GILIA -B

我知道这是 getopts 的正常/典型行为,我确信有办法解决这个问题...

有什么想法吗?

【问题讨论】:

    标签: bash getopts


    【解决方案1】:

    假设:(1)所有选项都是必需的并且(2)没有参数可以以'-'开头,那么我将使用这样的东西:

    while getopts ":a:b:" opt ; do
        [[ ${OPTARG} == -* ]] && { echo "Missing argument for -${opt}" ; exit 1 ; }
        case ${opt} in
            a ) gilia="$gilia $OPTARG"
                echo gilia $gilia
                ;;
            b ) gilib="$gilib $OPTARG"
                echo gilib $gilib
                ;;  
            \?) echo "Invalid (-${OPTARG}) option"
                ;;
            : ) echo "Missing argument for -${OPTARG}"
                ;;
        esac
    done
    

    你会得到:

    $ ./t.sh -a aaa -b bbb 
    gilia aaa
    gilib bbb
    $ ./t.sh -a -b bbb 
    Missing argument for -a
    $ ./t.sh -a aaa -b 
    gilia aaa
    Missing argument for -b
    $ ./t.sh -a aaa -b bbb -c ccc
    gilia aaa
    gilib bbb
    Invalid (-c) option
    

    【讨论】:

    • 好方法,我唯一要提的是,当没有传递任何选项或参数时,这不包括选项:“$ ./t.sh”,它什么也不返回
    • 很好的解决方案,谢谢!这里需要注意一点:如果您需要一个符合 POSIX 的脚本,您可以将参数值检查替换为以下内容(另外,它以 getopts 格式输出错误):if (echo "$OPTARG" | grep -Eq ^\\-.+$); then echo "$0: option requires an argument -- ${OPT}" exit 1 fi
    【解决方案2】:

    您可以做的是检查 $OPTARG 的值。如果它以- 开头,则减小索引$OPTIND 的值,以便在下一次循环中选择- 参数作为OPTION。

    在您的第二个示例中,在处理空 -A 参数时,$OPTIND 将设置为 3。我的代码会将值设置回 2,以便接下来处理 -B

        case $OPTION in
        A)
            arg=${OPTARG#-}
            if [ $arg == $OPTARG ]
            then
                GILIA="$GILIA $OPTARG"
                echo GILIA $GILIA
            else
                echo "-A needs argument"
                OPTIND=$OPTIND-1
            fi
            ;;
    

    【讨论】:

      【解决方案3】:

      如果您想将空白参数传递给-A,则:

      ./test_opt2 -A '' -B bbb
      

      如果您希望脚本在不带参数的情况下接受 -A,请更改脚本:

      while getopts "AB:" OPTION
      

      然后脚本会期望 -A 永远不会接受参数。

      【讨论】:

      • 它实际上并没有回答这个问题。问题是如果错误地丢失了选项的值,则指示错误。这不是允许故意省略该值或传递一个空值。
      猜你喜欢
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2015-11-05
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多