【问题标题】:Bash - using getops with multiple argumentsBash - 使用带有多个参数的 getopts
【发布时间】:2014-05-23 21:52:46
【问题描述】:

我有以下代码:

while getopts ":vh" opt; do
        case $opt in
         (h)
                helpMe
                exit 0
         ;;
         (v)
                version1
                exit 0
         ;;
         \?)
                echo -e "Invalid option: -$OPTARG\ntype -h for more help.\n" >&2
                exit 1
        ;;
        esac
done

此代码应仅获得标志“h”和“v”。 但是当我给出标志例如'hg'时,我仍然得到帮助输出。 另外,当我给出标志“va”时,我仍然得到版本输出。 我想说的是,我的脚本忽略了所需字母之后的所有字母。

为什么会这样? 有人可以请教吗?

谢谢。

【问题讨论】:

  • AFAIK opt 仅处理标志(单个字母)。所以hg 是帮助,g 是未知的。所以恕我直言,您的程序根据 opt 正确运行。你的期望是不同的。当你给它hg时它应该怎么做?中止?
  • no.get the help output
  • 我只是相信你的语法是错误的。而不是(h) 试试h)
  • @RedX, bash 实际上允许 both 形式,尽管在野外很少看到 (x) - 请参阅 bash 手册页,特别是模式之前的位: case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac.

标签: linux bash shell getopts


【解决方案1】:

循环一次解析和处理一个选项,-hg 被视为两个单独的选项,-h-g。由于循环首先遇到-h,它触发helpMe 并退出而不解析-g。如果您要使用 -gh 运行脚本,您会看到当它遇到 -g 选项时它会失败,因为在这种情况下它首先出现。

如果您不喜欢这种行为,您可以使用变量来存储状态,让getopts 完成解析并在之后测试-h

while getopts ":vh" opt; do
    case $opt in
        h)
            opt_h=true
            ;;
        [...]
    esac
done

if [ "${opt_h}" = true ]; then
    helpMe
    exit 0
fi

【讨论】:

  • 没错。但是它说没有解决方案吗?我只想使用“h”和“v”
  • @Assafbaruch 我不明白你的问题,你能改一下吗?
【解决方案2】:

在您的两个选择中都是对exit 的调用。 getopts 将处理参数一次一个,因此,当它遇到-h -g 中的h-hg 的扩展)时,它会运行helpMe,然后退出。

这意味着它永远不会在选项中找到-g

处理此问题的最简单方法是简单地声明,在-h 上,它将输出帮助文本并退出,而不管存在任何其他参数。

如果您想确保参数有效,只需将它们的状态存储在选项检查代码中,然后处理它们。

这样,检查将在任何操作之前完成。像这样的:

flag_v=0
flag_h=0
while getopts ":vh" opt; do
        case $opt in
         (h)
                flag_h=1
         ;;
         (v)
                flag_v=1
         ;;
         \?)
                echo -e "Invalid option: -$OPTARG\ntype -h for more help.\n" >&2
                exit 1
        ;;
        esac
done

if [[ $flag_h -eq 1 ]] ; then
    helpMe
    exit 0
fi
if [[ $flag_v -eq 1 ]] ; then
    showVersion
    exit 0
fi

# Now continue, neither h nor v was specified.

如果您指定-h-hv,这将提供帮助并退出,如果您指定-v,则会提供版本信息并退出,如果您提供任何其他选项,则会出现错误退出。

如果您指定 no 选项,它只会在注释之外继续执行您的脚本应该执行的任何操作。

【讨论】:

  • 您最初的回答准确地说明了我的所作所为,您的每次编辑都是基于我之前的编辑。看你的名声,我有点莫名其妙。
  • @Adrian,这经常发生。我没有专门查看您的答案(或其他任何人的一般答案),但我确实回答然后花一些时间思考是否可以改进它。我们最初的答案之间只有一分钟的事实意味着我们只是想法相同。我所做的编辑是为了澄清我之前的回答,以解决它。
猜你喜欢
  • 2013-04-17
  • 2021-06-09
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-25
  • 2011-11-23
  • 1970-01-01
相关资源
最近更新 更多