Bash 带有非选项和选项参数的脚本

Bash 带有非选项和选项参数的脚本,bash,getopts,Bash,Getopts,我正在尝试处理bash脚本的可选和必需参数。我有以下脚本: while getopts "a:x:" opt; do case $opt in a) echo "option a set: $OPTARG" ;; x) echo "option x set: $OPTARG" ;; \?) echo "Invalid option: -$OPTARG" >&2; exit 1;; esac done shift $((OPTIND-1)) ech

我正在尝试处理bash脚本的可选和必需参数。我有以下脚本:

while getopts "a:x:" opt; do
  case $opt in
     a) echo "option a set: $OPTARG" ;;
     x) echo "option x set: $OPTARG" ;;
     \?) echo "Invalid option: -$OPTARG" >&2; exit 1;;
esac
done
shift $((OPTIND-1))

echo "mandatory argument $1"
echo "mandatory argument2 $2"
使用以下命令运行脚本时,一切正常:

./script.sh -a optionA -x optionX mandatory1 mandatory2
但当我混合这些参数时:

./script.sh mandatory1 mandatory2 -a optionA -x optionX

它不。。。如何使其适用于所有参数组合?

我认为,您可以在这两种参数之间进行迭代

我认为这是您想要的,并允许您使用
--
来防止以下参数被解释为选项

mandatory=()
while [ $# -gt 0 ] && [ "$1" != "--" ]; do
  while getopts "a:x:" opt; do
    case $opt in
       a) echo "option a set: $OPTARG" ;;
       x) echo "option x set: $OPTARG" ;;
       \?) echo "Invalid option: -$OPTARG" >&2; exit 1;;
  esac
  done
  shift $((OPTIND-1))

  while [ $# -gt 0 ] && ! [[ "$1" =~ ^- ]]; do
    mandatory=("${mandatory[@]}" "$1")
    shift
  done
done

if [ "$1" == "--" ]; then
  shift
  mandatory=("${mandatory[@]}" "$@")
fi

echo "mandatory argument ${mandatory[0]}"
echo "mandatory argument2 ${mandatory[1]}"

基本上,这个想法是使用getopt使用所有选项,然后手动使用所有非选项,然后再次使用getopt查找更多选项。

为了使其工作,我必须在
shift$((OPTIND-1))之后取消OPTIND设置。


不同的顺序意味着不同的事情吗?如果没有,我不认为这样做有什么意义。@KarolyHorvath它的意思是完全相同的,这就是为什么它应该以完全相同的方式工作。但事实并非如此,没有什么不对的。这是一个unix(事实上?)标准,从标志开始…更具体地说,
getopts
只解析选项,直到它看到第一个参数不是以
-
开头。名称类似的外部程序
getopt
实现了更灵活的GNU风格的参数解析。很好,但如果将“-”作为“选项结束于此”分隔符处理,效果会更好。我现在测试了它并修复了错误。
[...]
shift $((OPTIND-1))
unset OPTIND
[...]