4

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

#!/bin/bash 

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

    shift $(($OPTIND - 1))
}

optsGet "${@}"
echo -e "CNAME: ${CNAME}\n"

但它仍然将空白/空值作为有效参数。所以,这有效:

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:]]*在函数中使用时不起作用。

4

2 回答 2

5

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

检查字符串是否仅包含空格。说:

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

代替

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

这也将处理 null ( \) 情况。

EDIT:其实也可以写成:

    c ) [[ -z "${OPTARG}" || "${OPTARG}" == *[[:space:]]* || "${OPTARG}" == -* ]] \
于 2013-08-29T11:45:43.837 回答
-1

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

于 2013-08-30T16:30:45.020 回答