Ich versuche, ein Shell-Skript aufzubauen, das verschiedene Optionen akzeptiert und getopts
eine gute Lösung zu sein scheint, da es die variable Reihenfolge der Optionen und Argumente handhaben kann (glaube ich!).
Ich verwende nur kurze Optionen und für jede kurze Option ist ein entsprechender Wert erforderlich, z. B.: ./command.sh -a arga -g argg -b argb
Ich möchte jedoch zulassen, dass die Optionen in einer unspezifischen Reihenfolge eingegeben werden, wie es die meisten Leute gewohnt sind, mit Shell-Befehlen zu arbeiten .
Der andere Punkt ist, dass ich meine eigenen Überprüfungen der Optionsargumentwerte durchführen möchte, idealerweise innerhalb der case
Anweisungen. Der Grund dafür ist, dass meine Tests :)
in meiner case
Erklärung zu inkonsistenten Ergebnissen geführt haben (wahrscheinlich durch mangelndes Verständnis meinerseits).
Zum Beispiel:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
War bei solchen Ereignissen fehlgeschlagen ... ./command.sh -d -h
Wenn ich möchte, dass -d als Argument erforderlich markiert wird, aber ich erhalte, dessen Wert -d=-h
nicht das ist, was ich brauche.
Daher dachte ich, es wäre einfacher, meine eigene Validierung innerhalb der case-Anweisungen durchzuführen, um sicherzustellen, dass jede Option nur einmal festgelegt und festgelegt wird.
Ich versuche Folgendes zu tun, aber meine if [ ! "$MYSQL_HOST" ]; then
Blöcke werden nicht ausgelöst.
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
if [ ! "$MYSQL_HOST" ]; then
echo "host not set"
exit 2
fi
;;
u)
MYSQL_USER=$OPTARG
if [ ! "$MYSQL_USER" ]; then
echo "username not set"
exit 2
fi
;;
p)
MYSQL_PASS=$OPTARG
if [ ! "$MYSQL_PASS" ]; then
echo "password not set"
exit 2
fi
;;
d)
BACKUP_DIR=$OPTARG
if [ ! "$BACKUP_DIR" ]; then
echo "backup dir not set"
exit 2
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
#:)
# echo "Option -$opt requires an argument" >&2
# exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
Gibt es einen Grund, warum ich nicht überprüfen kann, ob ein OPTARG
von innen eine Länge von Null hat getopts ... while ... case
?
Was ist der bessere Weg , mein eigenes Argument Validierung mit laufen getopts
in einem Fall , wo ich will auf das zu verlassen nicht :)
. Führen Sie meine Argumentvalidierung außerhalb des while ... case ... esac
?
Dann könnte ich mit Argumentwerten von -d
etc enden und keine fehlende Option abfangen.
while
Schleife über die Optionen läuft. Dies ist die Methode, mit der ich mich entschieden habe, obwohl sie im Vergleich zu anderen ausführlich ist, ist sehr klar, was im Skript vor sich geht. In diesem Fall ist die Wartbarkeit durch andere wichtig.