(类似于
this,但是在bash中.)
我有一个现有的bash脚本,它使用内置的getopts来识别-s(仅标记 – 无参数).我发现每次都使用该选项,所以除非在命令行中指定-s-或s,否则我希望将其设置为默认值.但是,虽然ksh getopts
can handle +s
,我在bash getopts
manual中找不到这种能力.
我目前的解决方法是:
>使用s:所以我可以通过$OPTARG =“ – ”来识别-s-;要么
>用不同的选项替换-s,例如-d(表示“不”).
然而,#1有一个问题,如果我不小心指定-s,它会吞下下一个参数,而#2的问题是它使用了与我肌肉记忆中已有的切换字母不同的切换字母.我希望可能有一种简单的方法来解析bash中的-s-或s.
> util-linux getopt(1)似乎也没有.它可以处理可选参数,因此可以采用-s-.但是,我之前没有使用过getopt(1),所以我会很高兴能够指出如何不用脚射击自己.
> BashFAQ 035说“自己解析”.如果你有一个已写入s或-s-的例程,我很乐意看到它.
我目前的arg-parsing循环非常基础:
while getopts "nthps" opt ; do
case "$opt" in
<other cases cut>
(s) saw_s="yes"
;;
esac
done
shift $((OPTIND-1))
最佳答案 负标志序列(abcdef g)与正常序列(-abcdef -g)的区别仅在于加号字符.所以你可以简单地恢复前缀的标志值.
第二种形式的负序是如此简单.只需删除最后一个字符( – ),并取消正常的标志值.
例
以下脚本接受所有提到的格式,例如-ns -n -s -n- -nsns ns s.
arglist='ns'
while (( $# )); do
arg="$1"
# Parse -abcdef- (negative form of -abcdef) options
if [ "${arg:0:1}" = '-' -a "${arg#${arg%?}}" = '-' ]; then
flag_val=no
arg="${arg%?}" # -abcdef- becomes -abcdef
elif [ "${arg:0:1}" = '+' ]; then
flag_val=no
arg="${arg/#+/-}"
else
flag_val=yes
fi
# OPTIND is the index of the next argument to be processed.
# We are going to parse "$arg" from the beginning, so we need
# to reset it to 1 before calling getopts.
OPTIND=1
while getopts "$arglist" opt "$arg"; do
case "$opt" in
s) saw_s="$flag_val" ;;
n) saw_n="$flag_val" ;;
esac
done
shift
done
# Set default values
: ${saw_s:=yes}
: ${saw_n:=no}
printf "saw_s='%s'\nsaw_n='%s'\n" "$saw_s" "$saw_n"
测试
$./pargs.sh
saw_s='yes'
saw_n='no'
$./pargs.sh -s
saw_s='yes'
saw_n='no'
$./pargs.sh +s
saw_s='no'
saw_n='no'
$./pargs.sh -s-
saw_s='no'
saw_n='no'
$./pargs.sh -s- +s -s
saw_s='yes'
saw_n='no'
$./pargs.sh -s +s
saw_s='no'
saw_n='no'
$./pargs.sh +s -s
saw_s='yes'
saw_n='no'
$./pargs.sh -s -s-
saw_s='no'
saw_n='no'
$./pargs.sh -sn
saw_s='yes'
saw_n='yes'
$./pargs.sh -sn -s-
saw_s='no'
saw_n='yes'
$./pargs.sh -sn +s
saw_s='no'
saw_n='yes'
$./pargs.sh +sn
saw_s='no'
saw_n='no'
$./pargs.sh -sn-
saw_s='no'
saw_n='no'
$./pargs.sh -sn- -n
saw_s='no'
saw_n='yes'