【问题标题】:Handling unused getopts argument处理未使用的 getopts 参数
【发布时间】:2019-02-18 12:11:55
【问题描述】:

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

USAGE() { echo -e "Usage: bash $0 [-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 还很陌生。我正在对此脚本进行一些测试,在某个阶段,我不需要/不想使用 -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

更新

做了一些测试后,我认为是这样的:

  • 如果你没有明确写“-c”,getopts 不会“询问”你并给你一个错误(除非你的脚本正在用它做一些事情 - 即如果你没有把 # 放在前面使用此参数的每个命令)
  • 只有输入“-c”才会报错

这对吗?

【问题讨论】:

    标签: bash parameter-passing command-line-arguments getopts


    【解决方案1】:

    你可以使用这个脚本:

    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 '\0%s\0%d\0' "$(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"

    【讨论】:

      【解决方案2】:

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

      通过在 Bash 代码中使用 nounset 设置(使用 set -o nounsetset -u),您可以获得强制参数的一种自动警告。如果未指定 -c 选项,因此未设置 $CONTAINER,这将导致对 echo $CONTAINER 之类的代码发出警告。但是,使用nounset 选项意味着您的所有代码需要更仔细地编写。有关详细信息,请参阅 How can I make bash treat undefined variables as errors?,包括 cmets 和“链接”答案。

      【讨论】:

        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-28
        • 1970-01-01
        相关资源
        最近更新 更多