我编写了一个bash脚本,它采用了灵活的参数,现在我想为每个参数添加一个可选参数(-l
)。
我目前难以获得理想的行为。
我希望以下所有内容都能正确执行:
./Script.sh arg1 arg2 arg3 -l opt
./Script.sh arg1 arg2 arg3
./Script.sh arg1 arg2 arg3 arg4 -l opt
./Script.sh arg1 arg2 arg3 arg4 arg5
问题是无法设置$OPTIND
。
如果-l opt
放在第一个参数之前,则以下循环有效。
while getopts ":l:" option
do
case "$option" in
t)
F_NAME=$OPTARG
;;
esac
done
shift $((OPTIND - 1))
但是,将可选-l
作为最后一个参数是必需的。
最简单的方法是什么?
答案 0 :(得分:2)
这是我发现使用带有getopts的可选参数的参数的技巧。
管理Janr Schampera在命令中可选参数的情况的方法是bash-hackers.org上的回复:
if [[ $OPTARG = -* ]]; then
((OPTIND--))
continue
fi
(参见:页面深处的http://wiki.bash-hackers.org/howto/getopts_tutorial) 但它没有管理在命令末尾给出选项的情况。
在这种情况下,这被认为是错误的,因为没有给出参数,getopts
将opt
变量设置为':'(冒号)和OPTARG
到故障选项值。
因此,我们必须使用case $OPTARG
管理“:”案例。
让我们说我们编写一个有三个选项的脚本:
a
:不带参数b
:带有必需参数v
:使用0
到2
的值设置详细程度。默认值为0
,并且当使用-v
调用脚本而没有参数或值不正确时使用的预设值。这是代码:
#!/bin/bash
VERBOSITY=0 # default verbosity set to 0
PRESET_VERBOSITY=1 # preset verbosity when asked
while getopts :ab:v: opt; do
case $opt in
a)
echo "manage option a"
;;
b)
echo "manage option b with value '$OPTARG'"
;;
v)
if [[ $OPTARG = -* ]]; then # Jan Schampera reply
echo "set verbosity to PRESET (no value given, not last position)"
VERBOSITY=$PRESET_VERBOSITY
((OPTIND--))
continue
fi
if [[ "$OPTARG" =~ ^[0-2]$ ]]; then
echo "set verbosity to $OPTARG (good value given)"
VERBOSITY=$OPTARG
else
echo "set verbosity to PRESET (bad value given)"
VERBOSITY=$PRESET_VERBOSITY
fi
;;
:)
case $OPTARG in
v)
echo "set verbosity to PRESET (no value given, last option)"
VERBOSITY=$PRESET_VERBOSITY
;;
esac
;;
\?)
echo "WTF!"
;;
esac
done
echo "**verbosity is set to $VERBOSITY**"
答案 1 :(得分:1)
getopts
符合posix标准命令行语法,其中标志选项首先出现。因此,对于非标准情况使用起来并不容易。
但是,您可能有getopt(1)
的Gnu实现(请参阅man 1 getopt
),它可以处理置换选项标志以及长选项。但是,它并不像界面那么容易。
或者你可以自己解释一下这个论点。
for ((i=1; i<=$#; ++i)); do
if [[ ${!i} == "-l" ]]; then
((++i))
OPT_L=${!i}
else
# handle the argument (in "${!i]")
fi
done
(注意:如果-l
出现在参数列表的末尾,上面不会抛出错误;它只是将选项值设置为空字符串。如果这不合适,它可能不是然后插入一些错误检查。)