如何遍历 bash 脚本标志并使用它们?

How do I iterate over bash script flags and use them?

我有一个用 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 ... 顺序给出标志时,它似乎无法工作(当我期望它是 [=15= 时,我得到 x is 0 ]).

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

用于此目的的代码应该是什么?我尝试了几个选项,但我没能弄清楚 synthax 到底应该是什么。

提前致谢。

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 成为缺失的参数,未被视为一个选项。这是您问题的原因吗?

Note: If you want to also use long options don't use the bash getopts builtin, use the getopt utility.