Verwenden von „case $1 in“ zum Lesen von Befehlsoptionen – mehrere Flags nach dem Bindestrich und Umgang mit ungewöhnlichen Flags?

Verwenden von „case $1 in“ zum Lesen von Befehlsoptionen – mehrere Flags nach dem Bindestrich und Umgang mit ungewöhnlichen Flags?

Ich erstelle ein Bash-Skript, das sowohl lange Optionen als auch kurze Flags verwendet. Da ich lange Optionen möchte, kann ich nicht verwenden getopts. Ich habe versucht, den folgenden Code zu verwenden:

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

Dies funktioniert, wenn ich es wie myscr -o -roder aufrufe myscr -h, aber wenn ich es versuche, myscr -orführt das Programm einfach sein normales Verhalten aus und myscr -or -hverlässt bei der Ausführung die Schleife, bevor es zu erreicht -h. Das Ersetzen breakdurch continueführt nur dazu, dass myscr -orund myscr -or -hhängen bleibt.

Antwort1

Probieren Sie das hier zur Veranschaulichung an:

#!/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

Beachten Sie, dass beim ersten Parameter, der keinem bestimmten Fall entspricht, die Parameteranalyse beendet wird, sodass a ./foobar.sh -o --help -s -rden nicht verarbeitet -r. Dies kann durch Ändern der *) break;;Zeile zur Fehlerbehandlung angepasst werden. Denken Sie jedoch daran, das pleaseshift=1! einzufügen.

Antwort2

Vielleicht reicht es, die gewünschte Zeile hinzuzufügen:

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

oder, komplexer, Sie können den caseBlock in eine Funktion mit dem shift 1out des Blocks, aber immer noch innerhalb des while einfügen.
Für denverdoppeltOptionen ( -or,, -ohdie nicht zu den langen gehören, können Sie rekursiv für jeden Buchstaben von case *)... dieselbe Funktion aufrufen. Sie benötigen ein Flag, wenn Sie gerade $1als lange Option verarbeitet haben. In diesem Fall setzen Sie Ihr Skript jedoch fehlerhaftem Verhalten aufgrund von Druckfehlern aus (z. B. wenn ich -overrider I will process-o -v -e -r -d` schreibe ...)

verwandte Informationen