【问题标题】:How do I iterate over bash script flags and use them?如何迭代 bash 脚本标志并使用它们?
【发布时间】:2022-01-13 12:00:32
【问题描述】:

我有一个用 bash 脚本包装的代码,我想知道是否给出了某个标志 (-b),如果是,则更新我在脚本中的一些变量(称为“x”) .不幸的是,我需要在 bash 脚本上完成此操作,而这里的合成器让我抓狂。我所做的一个小例子是(没有调用我包装的代码):

#!/bin/bash
x=0

while getopts :b opt; do
  case $opt in
    b) x=1;;
    ?) echo "";;
  esac
done

echo "x is ${x}"

我的问题是我想要传递给命令行的标志不止一个。 我尝试使用: while getopts :b:f:c opt; do...,但是当我没有在 -b -f ... -c ... 订单中提供标志时,它看起来无法正常工作(当我期望它是 x is 1 时,我得到了 x is 0)。

此外,当我想给出带有 -- 前缀(--frame 而不是 -f)的标志时,这不起作用。

为此目的的代码应该是什么?我尝试了几个选项,但我无法弄清楚合成器到底应该是什么。

提前谢谢你。

【问题讨论】:

  • 你的例子对我有用(不是长选项(--)部分):如果我通过-b,我会得到x is 1。你能提供一个minimal reproducible example吗?

标签: bash script getopts


【解决方案1】:

TL;DR

带参数的选项在optstring 中的字符之后 有一个冒号。所以getopts :b:c:f的意思是:

  • 您有一个带有参数的 -b 选项 (b:)
  • 您有一个带有参数的 -c 选项 (c:)
  • 您有一个不带参数的 -f 选项 (f)
  • 使用静默错误报告(前导冒号)

如果您在脚本中使用 while getopts :b:f:c opt; do... 并输入:

./script.sh -c -b -f

-b 被视为选项-c 的参数,而不是选项本身。

详情

考虑到您问题的这一部分:“当我没有在 -b -f ... -c ... 命令中给出标志时,它似乎无法正常工作”,让我们假设您希望 b 选项没有参数,而 fc 选项有一个。

如果您的选项没有参数,请不要在 optstring 参数中添加冒号;否则将冒号放在选项字符之后。通过您的简单示例,您可以尝试:

#!/bin/bash
x=0
fopt=""
copt=""

while getopts bf:c: opt; do
  case "$opt" in
    b) x=1;;
    f) echo "f option found"; fopt="$OPTARG";;
    c) echo "c option found"; copt="$OPTARG";;
    ?) echo "";;
  esac
done

echo "x is ${x}"
echo "fopt is ${fopt}"
echo "copt is ${copt}"

然后:

$ ./script.sh -b -c foo -f bar
c option found
f option found
x is 1
fopt is bar
copt is foo
$ ./script.sh -c foo -f bar
c option found
f option found
x is 0
fopt is bar
copt is foo
$ ./script.sh -c foo -b
c option found
x is 1
fopt is 
copt is foo

但要小心:对于最后一个示例,如果您省略了 -c 选项的 foo 参数:

./script.sh -c -b
c option found
x is 0
fopt is 
copt is -b

看到了吗? -b 成为缺失的参数,未被视为一种选择。是不是你的问题的原因?

注意:如果您还想使用长选项,请不要使用 bash getopts 内置函数,请使用 getopt 实用程序。

【讨论】:

  • 感谢您的详细解释!效果很好:)
猜你喜欢
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 2010-09-20
  • 2023-03-20
  • 2023-01-13
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
相关资源
最近更新 更多