我有一系列的bash脚本。
我使用getopts来解析来自命令行的参数(尽管可以选择)。
这些脚本有一系列通用选项调用此选项集
例如队列、士官等。
然后,每个脚本都有一系列额外选项,即设置b1、b2、b3。
我要的是剧本
"1 to be able to take options A+B1"
"2 to be able to take options A+B2"
"3 to be able to take options A+B2"
但我希望能够将选项a的代码存储在一个中心位置(库/函数),而不必在每个脚本中编写。
我想要的是一种在getopts中插入泛型代码的方法。或者是运行getopts两次的方法。
事实上,我是通过将getopts作为一个源函数来实现的。
但问题是我无法得到未被认可的选择来工作他们。
我想一种方法是在传递给b1、b2、b3等的getopts之前从字符串的选项a中删除参数?
谢谢罗杰
最佳答案
这是一个非常好的问题,要回答这个问题,我们需要很好地理解getopts
是如何工作的。
这里的关键点是getopts
被设计成在单个循环中迭代提供的参数。因此,问题的解决方案是在不同的文件之间分割循环,而不是运行命令两次:
#!/usr/bin/env bash
# File_1
getopts_common() {
builtin getopts ":ab:${1}" ${2} ${@:3} || return 1
case ${!2} in
'a')
echo 'a triggered'
continue
;;
'b')
echo "b argument supplied -- ${OPTARG}"
continue
;;
':')
echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
exit 1
;;
esac
}
#!/usr/bin/env bash
# File_2
# source "File_1"
while getopts_common 'xy:' OPTKEY ${@}; do
case ${OPTKEY} in
'x')
echo 'x triggered'
;;
'y')
echo "y argument supplied -- ${OPTARG}"
;;
'?')
echo "INVALID OPTION -- ${OPTARG}" >&2
exit 1
;;
':')
echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
exit 1
;;
*)
echo "UNIMPLEMENTED OPTION -- ${OPTKEY}" >&2
exit 1
;;
esac
done
实施说明
我们从
File_2
开始,因为脚本的执行就是从这里开始的:我们不是直接调用
getopts
,而是通过它的代理调用它:getopts_common
,代理负责处理所有公共选项。getopts_common
函数调用时使用:一个字符串,定义期望的选项以及期望它们的参数的位置。此字符串仅包含
File_2
中定义的选项。用于选项报告的shell变量的名称。
命令行参数的列表。(这简化了从
getopts_common
函数内部访问它们的过程。)转到源文件(
File_1
)时,我们需要记住getopts_common
函数在File_2
中定义的while循环内运行:getopts
返回false
如果没有要解析的内容,|| return 1
位确保getopts_common
函数执行相同的操作。当处理有效选项时,执行需要转到循环的下一个迭代。因此,每个有效的选项都以
continue
结尾。无提示错误报告(当optspec以
:
开头时启用)允许我们区分INVALID OPTION
和MISSING ARGUMENT
。后面的错误是特定于File_1
中定义的公共选项的,因此需要将其困在那里。有关
getopts
的详细信息,请参见Bash Hackers Wiki: Getopts tutorial