我正在编写一个bash-shell脚本,该脚本可以使用标志-l
-u
和-w [argument]
我有以下(简化(代码:
while getopts ":ulw:" arg; do
case "$arg" in
u)
U=1
;;
l)
L=1
;;
w)
W=1
VALUE="${OPTARG}"
;;
esac
done
当我用-w42 -l
运行我的脚本时,它的工作方式是应该的。如果我使用-lw42
,它也起作用,但当我使用-w42l
时,它认为42l
是自变量(而不仅仅是42
(,它使VALUE
变量=42l
,并忽略-l
选项。
如何使脚本同时适用于-w42 -l
、-lw42
和-w42l
?
关于标准合规性
你所做的尝试一开始就不应该奏效。
POSIX实用程序语法指南#5指出:
当分组在一个"-"分隔符后时,应接受一个或多个没有选项参数的选项,后面最多跟一个带有选项参数的选择。
因此,带有选项参数的选项(在本例中为-w
(只允许是由单个-
启动的组中的最后一个。
关于如何让它发挥作用
如果不能处理符合标准的行为,就不能使用getopts
,因此需要编写自己的逻辑。这样做的一种方法可能如下:
#!/usr/bin/env bash
# ^^^^- note bash, not sh; the below code uses non-POSIX extensions
while (( $# )) && [[ $1 = -* ]]; do
arg=${1#-}; shift
while [[ $arg ]]; do
case $arg in
l*) flag_l=1; arg=${arg#l};;
u*) flag_u=1; arg=${arg#u};;
w*)
flag_w=1
rest=${arg#w}
if [[ -z $rest ]]; then
arg=$1; shift; rest=$arg
fi
if [[ $rest =~ ^([[:digit:]]+)(.*) ]]; then
w_value=${BASH_REMATCH[1]}
arg=${BASH_REMATCH[2]}
else
echo "ERROR: -w not followed with a number" >&2
exit 1
fi
;;
*) echo "Unrecognized flag: $arg" >&2; exit 1;;
esac
done
done
echo "After parsing:"
echo "flag_w = ${flag_w:-0}"
echo "flag_l = ${flag_l:-0}"
echo "flag_u = ${flag_u:-0}"
echo "w_value = ${w_value:-0}"
请在上的在线解释器中查看此运行https://ideone.com/eDrlHd