Ich versuche, ein Shell-Skript zu erstellen, das so ausgeführt werden soll:
script.sh -t application
Zunächst möchte ich in meinem Skript überprüfen, ob das Skript mit dem Flag -t ausgeführt wurde. Wenn es zum Beispiel ohne dieses Flag ausgeführt wurde, möchte ich, dass es einen Fehler macht:
script.sh
Zweitens möchte ich unter der Annahme, dass ein -t-Flag vorhanden ist, den Wert abrufen und in einer Variablen speichern, die ich beispielsweise in meinem Skript verwenden kann:
FLAG="application"
Bisher konnte ich nur Fortschritte machen, indem $ @ alle Befehlszeilenargumente erfasst, aber ich weiß nicht, wie dies mit Flags zusammenhängt oder ob dies überhaupt möglich ist.
Antworten:
Sie sollten dieses getopts- Tutorial lesen .
Beispiel mit einem
-a
Schalter, für den ein Argument erforderlich ist:#!/bin/bash while getopts ":a:" opt; do case $opt in a) echo "-a was triggered, Parameter: $OPTARG" >&2 ;; \?) echo "Invalid option: -$OPTARG" >&2 exit 1 ;; :) echo "Option -$OPTARG requires an argument." >&2 exit 1 ;; esac done
Wie Greybot sagte (
getopt
! =getopts
):quelle
getopts
ist einbash
integriertesgetopt
Programm , aber es gibt auch ein externes Programm, das mit jeder POSIX-kompatiblen Shell funktionieren sollte.getopts
Tutorial ist einfach und bietet hilfreiche Beispiele. Auf jeden Fall lesenswert, wenn Sie auf diesen Beitrag stoßen.Verwenden Sie
$#
diese Option, um die Anzahl der Argumente zu ermitteln. Wenn sie ungleich 2 ist, werden nicht genügend Argumente bereitgestellt:if [ $# -ne 2 ]; then usage; fi
Überprüfen Sie als nächstes, ob
$1
gleich ist-t
, andernfalls wurde ein unbekanntes Flag verwendet:if [ "$1" != "-t" ]; then usage; fi
Schließlich speichern
$2
inFLAG
:FLAG=$2
Hinweis:
usage()
Ist eine Funktion, die die Syntax anzeigt. Zum Beispiel:function usage { cat << EOF Usage: script.sh -t <application> Performs some activity EOF exit 1 }
quelle
Hier ist eine verallgemeinerte einfache Befehlsargumentschnittstelle, die Sie oben in alle Ihre Skripte einfügen können.
#!/bin/bash declare -A flags declare -A booleans args=() while [ "$1" ]; do arg=$1 if [ "${1:0:1}" == "-" ] then shift rev=$(echo "$arg" | rev) if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "${rev:0:1}" == ":" ] then bool=$(echo ${arg:1} | sed s/://g) booleans[$bool]=true echo \"$bool\" is boolean else value=$1 flags[${arg:1}]=$value shift echo \"$arg\" is flag with value \"$value\" fi else args+=("$arg") shift echo \"$arg\" is an arg fi done echo -e "\n" echo booleans: ${booleans[@]} echo flags: ${flags[@]} echo args: ${args[@]} echo -e "\nBoolean types:\n\tPrecedes Flag(pf): ${booleans[pf]}\n\tFinal Arg(f): ${booleans[f]}\n\tColon Terminated(Ct): ${booleans[Ct]}\n\tNot Mentioned(nm): ${boolean[nm]}" echo -e "\nFlag: myFlag => ${flags["myFlag"]}" echo -e "\nArgs: one: ${args[0]}, two: ${args[1]}, three: ${args[2]}"
Durch Ausführen des Befehls:
bashScript.sh firstArg -pf -myFlag "my flag value" secondArg -Ct: thirdArg -f
Die Ausgabe lautet wie folgt:
"firstArg" is an arg "pf" is boolean "-myFlag" is flag with value "my flag value" "secondArg" is an arg "Ct" is boolean "thirdArg" is an arg "f" is boolean booleans: true true true flags: my flag value args: firstArg secondArg thirdArg Boolean types: Precedes Flag(pf): true Final Arg(f): true Colon Terminated(Ct): true Not Mentioned(nm): Flag: myFlag => my flag value Args: one => firstArg, two => secondArg, three => thirdArg
Grundsätzlich sind die Argumente in Flags, Boolesche Werte und generische Argumente unterteilt. Auf diese Weise kann ein Benutzer die Flags und Booleschen Werte an einer beliebigen Stelle platzieren, solange er die generischen Argumente (falls vorhanden) in der angegebenen Reihenfolge aufbewahrt.
Erlauben Sie mir und jetzt Ihnen, sich nie wieder mit dem Parsen von Bash-Argumenten zu befassen!
Sie können eine aktualisierte Skript sehen hier
Dies war im letzten Jahr enorm nützlich. Es kann jetzt den Bereich simulieren, indem den Variablen ein Bereichsparameter vorangestellt wird.
Nennen Sie einfach das Skript wie
replace() ( source $FUTIL_REL_DIR/commandParser.sh -scope ${FUNCNAME[0]} "$@" echo ${replaceFlags[f]} echo ${replaceBooleans[b]} )
Sieht nicht so aus, als hätte ich den Argumentationsbereich implementiert. Ich bin mir nicht sicher, warum ich ihn wohl noch nicht gebraucht habe.
quelle
source arg_handler; arg_handler "$@"
Versuchen Sie shFlags - Erweiterte Befehlszeilen-Flag-Bibliothek für Unix-Shell-Skripte.
http://code.google.com/p/shflags/
Es ist sehr gut und sehr flexibel.
FLAGGENTYPEN: Dies ist eine Liste der DEFINE _ *, die Sie ausführen können. Alle Flags haben einen Namen, einen Standardwert, eine Hilfezeichenfolge und einen optionalen Kurznamen (Ein-Buchstaben-Name). Einige Flags haben andere Argumente, die mit dem Flag beschrieben werden.
DEFINE_string: Nimmt jede Eingabe und stellt sie als Zeichenfolge dar.
DEFINE_boolean: Nimmt normalerweise kein Argument an: Sagen Sie --myflag, um FLAGS_myflag auf true zu setzen, oder --nomyflag, um FLAGS_myflag auf false zu setzen. Alternativ können Sie sagen --myflag = true oder --myflag = t oder --myflag = 0 oder --myflag = false oder --myflag = f oder --myflag = 1 Das Übergeben einer Option hat den gleichen Effekt wie das Übergeben von Option einmal.
DEFINE_float: Nimmt eine Eingabe und stellt sie als Gleitkommazahl dar. Da die Shell Floats per se nicht unterstützt, wird die Eingabe lediglich als gültiger Gleitkommawert validiert.
DEFINE_integer: Nimmt eine Eingabe und stellt sie als Ganzzahl dar.
SPEZIELLE FLAGGEN: Es gibt einige Flags, die eine besondere Bedeutung haben: --help (oder -?) Gibt eine Liste aller Flags auf lesbare Weise aus --flagfile = foo liest Flags von foo. (noch nicht implementiert) - Beendet wie in getopt () die Flag-Verarbeitung
BEISPIELVERWENDUNG:
-- begin hello.sh -- ! /bin/sh . ./shflags DEFINE_string name 'world' "somebody's name" n FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" echo "Hello, ${FLAGS_name}." -- end hello.sh -- $ ./hello.sh -n Kate Hello, Kate.
Hinweis: Ich habe diesen Text aus der Shflags-Dokumentation übernommen
quelle