如何阻止getopts将blank或null或其他选项作为选项值



我(大概每个人)都会遇到这个问题,但我自己找不到任何好的解决方法。当getopts查找一个参数时,它实际上会获取下一个参数,即使它是一个选项。这就是我所做的阻止(代码片段):

#!/bin/bash 
function optsGet()
{
    while getopts ":c:f" opt; do
        case $opt in
            c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] 
                && { echo -e "ERROR: Invalid argumentn"; exit 1; }
                CNAME="${OPTARG}.tEsTsTr"
                ;;
            f ) FORCE=true
                ;;
            ?) echo -e "Invalid option: -$OPTARGn" >&2;;
            : ) echo -e "Missing argument for -$OPTARGn" >&2; exit 1;;
            * ) echo -e "Unimplemented option: -$OPTARGn" >&2; exit 1;;
        esac
    done
    shift $(($OPTIND - 1))
}
optsGet "${@}"
echo -e "CNAME: ${CNAME}n"

但它仍然将blank/null作为有效的参数。所以,这是有效的:

san@AM0150 testtools$ ./getopts.sh -c -f
ERROR: Invalid argument

但这些不是:

san@AM0150 testtools$ ./getopts.sh -c " " -f
CNAME:  .tEsTsTr
san@AM0150 testtools$ ./getopts.sh -c   -f
CNAME:  .tEsTsTr

我很期待Missing argument for -c错误。这里有我遗漏的东西吗?或者有人知道变通办法吗?如有任何意见,我们将不胜感激。干杯


更新(主要基于devnull的回复):

为了完整起见,现在我有了一个小函数:

function ifEmpty()
{
    local VAL=$1
    local OPT=$2
    [[ -z "${VAL}" || "${VAL}" =~ ^[[:space:]]*$ || "${VAL}" == -* ]] 
    && { echo -e "n  ERROR: Missing argument for option: -${OPT}n" >&2; exit 1; }
}

那么这个可以这样使用:

c ) ifEmpty "${OPTARG}" "${opt}"
    CNAME=${OPTARG//[[:space:]]}
    ;;

所有需要论证的选项。干杯

PS。由于某些原因,*[[:space:]]*在函数中使用时不起作用。

-z将为空字符串返回true,而不是为包含空格的字符串返回true。

检查字符串是否仅由空格组成。说:

    c ) [[ -z "${OPTARG}" || "${OPTARG}" =~ ^[[:space:]]*$ || "${OPTARG}" == -* ]] 

而不是

    c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] 

这也将处理null()情况。

EDIT:实际上,它也可以写成:

    c ) [[ -z "${OPTARG}" || "${OPTARG}" == *[[:space:]]* || "${OPTARG}" == -* ]] 

这可能是一个不回答的答案,但我不会试图阻止它。如果-c以文件名为参数,比如说,-f可能是有效的文件名, (空格)也是如此。一般来说,我不认为shell脚本应该做一些"有用"的事情,比如修剪空白或抛出不寻常但技术上有效的参数。

最新更新