处理未使用的 getopts 参数

Handling unused getopts argument

我有一个以 getopts 开头的脚本,如下所示:

USAGE() { echo -e "Usage: bash [=10=] [-w <in-dir>] [-o <out-dir>] [-c <template1>] [-t <template2>] \n" 1>&2; exit 1; }

if (($# == 0))
then
    USAGE
fi

while getopts ":w:o:c:t:h" opt
do
    case $opt in
        w ) BIGWIGS=$OPTARG
        ;;
        o ) OUTDIR=$OPTARG
        ;;
        c ) CONTAINER=$OPTARG
        ;;
        t ) TRACK=$OPTARG
        ;;
        h ) USAGE
        ;;
        \? ) echo "Invalid option: -$OPTARG exiting" >&2
        exit
        ;;
        : ) echo "Option -$OPTARG requires an argument" >&2
        exit
        ;;
    esac
done

more commands etc

echo $OUTDIR
echo $CONTAINER

我对 getopts 还很陌生。我正在对该脚本进行一些测试,在某个阶段,我没有 need/want 使用 -c 参数 [-c ]。换句话说,我试图测试脚本的另一个完全不涉及 $CONTAINER 变量的特定部分。因此,我简单地在所有带有 $CONTAINER 的命令前添加了 # 并做了一些测试,这很好。

在不使用 $CONTAINER 测试脚本时,我输入了:

bash script.bash -w mydir -o myoutdir -t mywantedtemplate

但是,我想知道,根据我的 getopts 命令,我没有收到警告。换句话说,为什么我没有收到要求 -c 参数的警告。这可能吗?警告是否仅在我键入时出现:

bash script.bash -w mydir -o myoutdir -t mywantedtemplate -c

更新

经过一些测试,我认为是这样:

这是正确的吗?

getopts 不会在某些选项未使用时发出警告(即它们是 可选的 )。通常这是一件好事,因为某些选项(例如 -h)不与其他选项一起使用。无法直接使用 Bash 内置 getopts 指定强制选项。如果您想要强制选项,那么您将需要编写代码来检查它们是否已被使用。参见 bash getopts with multiple and mandatory options。此外(如您所见),如果您未能编写代码来处理 getopts.

optstring(第一个)参数中指定的选项,则不会出现错误

通过在 Bash 代码中使用 nounset 设置(使用 set -o nounsetset -u),您可以获得一种针对强制参数的自动警告。如果未指定 -c 选项,因此未设置 $CONTAINER,这将导致针对 echo $CONTAINER 之类的代码发出警告。但是,使用 nounset 选项意味着需要更仔细地编写 all 代码。有关详细信息,请参阅 ,包括评论和 "Linked" 答案。

您可能会使用这个脚本:

printf捕获stdout并放入stderr然后返回stdout也捕获exit代码,所以我们可以处理如果代码大于 0.

some_command() {
    echo 'this is the stdout'
    echo 'this is the stderr' >&2
    exit 1
}

run_command() {
    {
        IFS=$'\n' read -r -d '' stderr;
        IFS=$'\n' read -r -d '' stdout;
        (IFS=$'\n' read -r -d '' _ERRNO_; exit ${_ERRNO_});
    } < <((printf '[=10=]%s[=10=]%d[=10=]' "$(some_command)" "${?}" 1>&2) 2>&1)
}

echo 'Run command:'
if ! run_command; then
    ## Show the values
    typeset -p stdout stderr
else
    typeset -p stdout stderr
fi

只需将 some_command 替换为 getopts ":w:o:c:t:h"