当getopts
刚刚停止一起运行时,我开始理解。当我在小型个人测试中尝试getopts
时,它的工作原理非常完美。我一直盯着屏幕看了两天,现在出了什么问题,我什至使用了一个shellchecker,它说一切正常。我试图在getopts
while循环内回显,但从未打印过,更不用说在情况下的回显了。这基本上就是我的代码,
helpmenu(){
case $1 in
general)
echo "Usage, some operationtypes, -h or --help idenifier explained"
;;
eachoperationtype)
echo "Explain this operationtype"
;;
}
operationtype=$1
if [[ operationtype == "Operation1" ]]; then
# Setting some variables to default values here
var1=0 #Default values
var2=4
var3=5
...
echo "this prints" # this prints
while getopts ":hs:d:m:f:a" opt; do
echo "does not print" # this does not print
case ${opt} in
h )
helpmenu operationtype #Simple function that prints out script usage
;;
s )
var=$OPTARG
;;
d )
var2=$OPTARG
;;
m )
var3=$OPTARG
;;
f )
var4=$OPTARG
;;
a )
bool=true
;;
\? )
echo "Syntax error: Unrecognised flags given"
helpmenu operationtype
;;
: )
echo "Syntax error: Invalid number of arguments"
helpmenu general # No arguments given - shows help menu with operationtypes so they can ./Script operationtype -h
;;
esac
done
shift $((OPTIND -1))
# Do some other stuff, works fine
#Other operations have similar structure to operationtype1
elif [[ operationtype == "operation2" ]]; then
# Similar program, potentially different flags, function, meaning etc
fi
脚本的要点是接受初始的第一个参数,该参数是所需的操作类型,并在初始{{1}之后的不同getopts
中运行不同的elifs
}。每个参数都会接受特定数量的参数以及一系列可选标志。也就是说,您可能有一个执行if
的脚本,例如可以执行./Script greetings "hello" -t 3
3次,并且在同一脚本echo "hello"
中具有另一个功能,例如可以在列表中提供user1的使用期限。我要处理的另一个问题是所需变量的设置,所需变量通常应正常收集而没有标志。问题是我想为每种操作类型弹出一个帮助菜单(快速使用)-即./Script age -u User1
返回operation1的帮助菜单,但是我不允许这种语法,因为在尝试设置时会返回错误必需的参数。另外,我还需要确保为每种操作类型放置正确数量的必需参数,因为其他任何数量都会导致错误。感谢您的任何提前帮助。
编辑:
我已经使用shellcheck.net检查了我的代码,并且我相信没有基于语法的错误。我并不需要真正的代码细节方面的帮助,而是我上面所强调的粗略想法,是获得所需结果的最佳方法是什么。这是解决此问题的最佳方法吗?如何获得基于./Script operation1 -h
的{{1}}功能?为什么operationtype
没有运行?抱歉,如果您有任何混淆,我将删除pastebin链接,因为这根本不是我的意图。
答案 0 :(得分:3)
问题中的ASK与getopt的“传统”用法之间的主要区别在于命令行参数遵循以下结构
script sub-command [options] arguments
getopt的“传统”用例预计会出现以下情况(该命令可能从选项中隐含,或者是参数列表的一部分)。
script [options] arguments
这里需要进行一些小的更改,提示getopt应该忽略第一个命令行参数。两种选择:转移参数列表,或更新OPTIND以跳过那些参数
# SHIFT the command outside the argument list
operationtype=$1
shift
if [[ operationtype == "Operation1" ]]; then
# Execute the operation 1
...
while getopts ":hs:d:m:f:a" opt; do
...
done
或更新OPTIND以跳过第一个参数1。
operationtype=$1
OPTIND=$((OPTIND+1))
if [[ operationtype == "Operation1" ]]; then
# Execute the operation 1
...
while getopts ":hs:d:m:f:a" opt; do
...
done
注意:每种解决方案都可用于提供2套选项。一种用于脚本,另一种用于子命令。例如,docker
命令行:
docker [options] sub-command [sub-command options]
原始答案:
已完全修订以解决OP所做的更改。