使用“case $1 in”读取命令选项-破折号后的多个标志,并处理不寻常的标志?

使用“case $1 in”读取命令选项-破折号后的多个标志,并处理不寻常的标志?

我正在编写一个使用长选项和短标志的 bash 脚本。由于我想要长选项,所以我不能使用getopts。我尝试使用以下代码:

while test -n "$1"; do
  case "$1" in
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

myscr -o -r当我像或一样调用它时,它可以工作myscr -h,但是当我尝试myscr -or程序仅运行它的正常行为时,myscr -or -h它在运行之前退出循环-h。 用 替换break只会continue导致myscr -ormyscr -or -h挂起。

答案1

试穿一下这个尺码:

#!/bin/bash
pleasereset=1
while test -n "$1"; do
   pleaseshift=0
   [[ pleasereset -eq 1 ]] && thisvar=$1 && pleasereset=0;
   case "$thisvar" in
      -o*|--override) echo "override!"; pleaseshift=1;;
      -r*|--reset) echo "reset!"; pleaseshift=1;;
      -h*|--help) echo "help!"; pleaseshift=1;;
      *) break ;;
   esac
   if [[ "$pleaseshift" = "1" ]];
   then
      testvar=${thisvar##-}
      if [[ ${#testvar} -gt 1 ]] && [[ ! ${thisvar} = --* ]];
      then
         thisvar=-$( echo "$testvar" | cut -c 2- )
      else
         shift 1; pleasereset=1;
      fi
   fi
done

请注意,在第一个不匹配任何特定情况的参数处,参数解析将停止,因此 a./foobar.sh -o --help -s -r将不会处理-r。这可以通过将*) break;;行更改为错误处理来调整,但请记住将pleaseshift=1!

答案2

也许添加您想要的行就足够了:

while test -n "$1"; do
  case "$1" in
        -or|-ro)        OV_RESET=yes;NO_CHANGE=yes;shift 1;;
        -o|--override)  NO_CHANGE=yes;shift 1;;
        -r|--reset)     OV_RESET=yes;shift 1;;
        -h|--help)      hthemehelp;shift 1;;
        *)              break;;
  esac
done

或者,更复杂一点,你可以将case块放在一个函数中,shift 1该函数位于该块之外,但仍在 while 内。
对于加倍选项(-or,,-oh不是长选项之一,您可以对每个字母递归调用相同的函数case *)...如果您刚刚将其$1作为长选项处理,则需要一个标志。在这种情况下,然而,由于打印错误,您的脚本会暴露出不良行为(例如,如果我写-overrider I will process-o -v -e -r -d`...)

相关内容