bash getopts使用选项/标志作为参数



我正在编写一个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

最新更新