973 Stimmen

Überprüfen Sie die Anzahl der Argumente, die an ein Bash-Skript übergeben wurden

Ich möchte, dass mein Bash-Skript eine Fehlermeldung ausgibt, wenn die erforderliche Argumentanzahl nicht erreicht wird.

Ich habe den folgenden Code ausprobiert:

#!/bin/bash
echo Skriptname: $0
echo Anzahl der Argumente: $#
if [$# -ne 1]; 
    then echo "ungültige Anzahl von Parametern"
fi

Aus irgendeinem unbekannten Grund habe ich den folgenden Fehler erhalten:

test: Zeile 4: [2: Befehl nicht gefunden

Was mache ich falsch?

1486voto

konsolebox Punkte 66082

Genau wie jeder andere einfache Befehl erfordert [ ... ] oder test Leerzeichen zwischen den Argumenten.

if [ "$#" -ne 1 ]; then
    echo "Ungültige Anzahl von Parametern"
fi

Oder

if test "$#" -ne 1; then
    echo "Ungültige Anzahl von Parametern"
fi

Vorschläge

Wenn Sie in Bash sind, bevorzugen Sie die Verwendung von [[ ]], da es kein Wort-Splitting und Pfadnamenerweiterung für seine Variablen durchführt, für die das Anführungszeichen möglicherweise nicht erforderlich ist, es sei denn, es handelt sich um Teil eines Ausdrucks.

[[ $# -ne 1 ]]

Es hat auch einige andere Funktionen wie unquoted Bedingungsgruppierung, Musteranpassung (erweitertes Muster-Matching mit extglob) und Regex-Matching.

Das folgende Beispiel überprüft, ob die Argumente gültig sind. Es erlaubt ein einzelnes Argument oder zwei.

[[ ($# -eq 1 || ($# -eq 2 && $2 == )) && $1 =~  ]]

Für reine arithmetische Ausdrücke ist die Verwendung von (( )), für einige möglicherweise immer noch besser, aber sie sind auch in [[ ]] mit ihren arithmetischen Operatoren wie -eq, -ne, -lt, -le, -gt oder -ge möglich, indem der Ausdruck als einzelnes Zeichenfolgenargument platziert wird:

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Druckt true.

Das sollte hilfreich sein, wenn Sie es auch mit anderen Funktionen von [[ ]] kombinieren müssen.

Beachten Sie, dass [[ ]] und (( )) Schlüsselwörter sind, die auf derselben Ebene der Analyse wie if, case, while und for liegen.

Auch wie Dave vorgeschlagen hat, sind Fehlermeldungen besser nach stderr geschickt, damit sie nicht eingeschlossen werden, wenn stdout umgeleitet wird:

echo "Ungültige Anzahl von Parametern" >&2

Beenden des Skripts

Es ist auch logisch, das Skript zu beenden, wenn ungültige Parameter übergeben werden. Dies wurde bereits in den Kommentaren von ekangas vorgeschlagen, aber jemand hat diese Antwort bearbeitet, um sie mit -1 als zurückgegebener Wert zu haben, also könnte ich es genauso gut richtig machen.

-1 wird zwar von Bash als Argument für exit akzeptiert, ist jedoch nicht explizit dokumentiert und sollte nicht als häufige Empfehlung verwendet werden. 64 ist auch der formalste Wert, da er in sysexits.h mit #define EX_USAGE 64 /* Kommandozeilen-Fehler */ definiert ist. Die meisten Tools wie ls geben auch 2 bei ungültigen Argumenten zurück. Früher habe ich auch 2 in meinen Skripts zurückgegeben, aber in letzter Zeit hat es mich nicht mehr wirklich interessiert, und habe einfach in allen Fehlern 1 verwendet. Aber lassen Sie uns hier einfach 2 platzieren, da es am häufigsten vorkommt und wahrscheinlich nicht betriebssystemspezifisch ist.

if [[ $# -ne 1 ]]; then
    echo "Ungültige Anzahl von Parametern" >&2
    exit 2
fi

Referenzen

107voto

Es könnte eine gute Idee sein, arithmetische Ausdrücke zu verwenden, wenn Sie mit Zahlen umgehen.

if (( $# != 1 )); then
    >&2 echo "Ungültige Anzahl von Parametern"
fi

>&2 wird verwendet, um die Fehlermeldung nach stderr zu schreiben.

47voto

jhvaras Punkte 1828

Am []: !=, =, == ... sind Zeichenfolgen Vergleichsoperatoren und -eq, -gt ... sind arithmetische binäre Operatoren.

Ich würde verwenden:

if [ "$#" != "1" ]; then

Oder:

if [ $# -eq 1 ]; then

37voto

Pat Punkte 15797

Wenn Sie nur daran interessiert sind, abzubrechen, wenn ein bestimmtes Argument fehlt, ist Parameter Substitution großartig:

#!/bin/bash
# usage-message.sh

: ${1?"Verwendung: $0 ARGUMENT"}
#  Skript bricht hier ab, wenn Befehlszeilenparameter fehlt,
#+ mit folgender Fehlermeldung.
#    usage-message.sh: 1: Verwendung: usage-message.sh ARGUMENT

16voto

Dwight Spencer Punkte 1367

Ein einfacher Befehl, der funktioniert, kann wie folgt durchgeführt werden:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

Dies lässt sich folgendermaßen aufschlüsseln:

  1. Teste die Bash-Variable auf die Größe der Parameter $ #, nicht gleich 1 (unsere Anzahl an Unterbefehlen)
  2. Wenn wahr, rufe die Funktion "usage()" auf und beende mit dem Status 1
  3. Ansonsten rufe die Funktion "main()" auf

Zu beachten:

  • Usage() kann einfach echo "$0: params" sein
  • Main kann ein langes Skript sein

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X