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 -r
oder aufrufe myscr -h
, aber wenn ich es versuche, myscr -or
führt das Programm einfach sein normales Verhalten aus und myscr -or -h
verlässt bei der Ausführung die Schleife, bevor es zu erreicht -h
. Das Ersetzen break
durch continue
führt nur dazu, dass myscr -or
und myscr -or -h
hä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 -r
den 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 case
Block in eine Funktion mit dem shift 1
out des Blocks, aber immer noch innerhalb des while einfügen.
Für denverdoppeltOptionen ( -or
,, -oh
die 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 $1
als 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 ...)