如何遍历 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
选项没有参数,而 f
和 c
选项有一个。
如果您的选项没有参数,请不要在 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.
我有一个用 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
选项没有参数,而 f
和 c
选项有一个。
如果您的选项没有参数,请不要在 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 thegetopt
utility.