Rückgabe eines Wertes von einer Bash-Funktion

Ich habe eine Funktion, die 1 zurückgibt, wenn die Zahl eine gültige zehnstellige Zahl ist:

valNum() { flag=1 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=0 fi return $flag } 

Es wird aufgerufen von:

if [[ $(valNum $num) -eq 1 ]]; then #do something fi 

Die Funktion funktioniert einwandfrei, wenn die Nummer gültig ist, aber Syntax anzeigt Fehler bei Eingabe einer ungültigen Nummer.

Antwort

@chorobas Antwort ist korrekt, dieses Beispiel könnte jedoch klarer sein:

valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi 

Dieses Beispiel ist etwas länger ($valNumResult setzen und dann diesen Wert abfragen), beschreibt jedoch genauer, was passiert: dass valNum() gibt einen Wert zurück, und dieser Wert kann abgefragt und getestet werden.

PS Bitte tun Sie sich selbst einen Gefallen und geben Sie 0 für true und ungleich Null für false. Auf diese Weise können Sie den Rückgabewert verwenden, um „warum wir fehlgeschlagen sind“ im Fehlerfall anzugeben.

Antwort

Funktionen in bash können nur Exit-Codes zurückgeben. Die Befehlssubstitution wird umgekehrt verwendet, um die Standardausgabe von a abzurufen Befehl oder Funktion. Um das zurückgegebene Flag zu überprüfen, benötigen Sie daher keine Ersetzung:

if valNum "$num" ; then # ... fi 

Damit dies funktioniert, sollten Sie jedoch 0 zurückgeben, wenn die Nummer ist gültig, und 1, wenn dies nicht der Fall ist (Exit-Code 0 bedeutet keinen Fehler).

Kommentare

  • Ich verstehe es nicht. Im Beispiel 24.7 in tldp.org/LDP/abs/html/complexfunct.html gibt die Funktion den Maximalwert und nicht den Exit-Code zurück. Obwohl Ihr Vorschlag funktioniert, kann ich nicht verstehen, warum er funktioniert
  • , da Ihr Test darin besteht, herauszufinden, ob die Eingabe eine gültige 10-stellige Ganzzahl ist oder nicht, dh wahr oder falsch, die Funktion gibt entweder 0 oder 1 zurück. Das Beispiel von choroba ‚ funktioniert, weil if valnum "$num" if valnum "$num" = 0 entspricht dh “ wenn es wahr ist „. Die Faustregel bei sh-Skripten lautet: 0 = wahr / Erfolg, ungleich Null = falsch / Fehler.
  • Übrigens, dass “ Advanced Bash-Scripting Guide “ ist nicht ‚ eine sehr gute Anleitung – ‚ ist in vielen Dingen falsch und ermutigt einige schlechte Skriptpraktiken. Die Bash-FAQ unter mywiki.wooledge.org/BashFAQ ist eine viel bessere Ressource.
  • siehe unix.stackexchange.com/questions/12236/ …
  • Ihre Funktion schlägt fehl, weil die Zeichenfolge “ Ungültige Nummer „, und Sie führen dann einen numerischen Vergleich zwischen dieser Zeichenfolge und der Nummer 1 mit if [[ $(valNum $num) -eq 1 ]]

Antwort

Sie können kein beliebiges Ergebnis von einer Shell-Funktion zurückgeben. Sie können nur einen Statuscode zurückgeben, der eine Ganzzahl zwischen 0 und 255 ist. (Während Sie einen größeren Wert an return übergeben können, wird er modulo 256 abgeschnitten.) Der Wert muss 0 sein Erfolg anzeigen und einen anderen Wert, um Misserfolg anzuzeigen; Konventionell sollten Sie sich an Fehlercodes zwischen 1 und 125 halten, da höhere Werte eine besondere Bedeutung haben (schlechter externer Befehl für 126 und 127, beendet durch ein Signal für höhere Werte).

Da Sie a zurückgeben Ja-oder-Nein-Ergebnis hier ist ein Statuscode angebracht. Da flag einen Erfolg oder Misserfolg anzuzeigen scheint, sollten Sie die herkömmlichen Werte 0 für Erfolg und 1 für Misserfolg verwenden (das Gegenteil von dem, was Sie geschrieben haben). Sie können Ihre Funktion dann direkt in einer if-Anweisung verwenden.

valNum () { local flag=0 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo 1>&2 "Invalid Number" flag=1 fi return $flag } if valNum "$num"; then #do something fi 

Wenn Sie zwischen Fehlercodes unterscheiden müssen, rufen Sie die Funktion direkt auf. Unmittelbar nach der Rückkehr ist der Fehlercode in $? verfügbar. Sie können dies dann mit einer case-Anweisung überprüfen:

valNum "$num" case $? in … 

Wenn Sie den Statuscode später verwenden müssen, speichern Sie ihn vor wird vom nächsten Befehl überschrieben.

valNum "$num" valNum_status=$? 

Was Sie geschrieben haben, hat nicht funktioniert, da die Befehlssubstitution $(…) wird auf die Ausgabe der Funktion erweitert, die in Ihrem Code entweder die Fehlermeldung oder leer ist, niemals 1.

Wenn erforderlich Um mehr Informationen zu übergeben, als ein Statuscode aus einer Shell-Funktion zulässt, haben Sie zwei Möglichkeiten:

  • Drucken Sie Text in der Standardausgabe und rufen Sie die Funktion in einer Befehlssubstitution auf: $(valNum "$num")
  • Weisen Sie einer oder mehreren Variablen innerhalb der Funktion zu und lesen Sie diese Variablen später.

Antwort

Ich habe selbst in diesem Bereich widersprüchliche Ergebnisse erzielt. Hier sind Ergebnisse meiner empirischen Experimente.Zunächst eine „ Theorie “ zu Bash- oder * nix-Befehlen:

  • SUCCESS == 0 … nämlich. kein Fehlerstatuscode)
  • FAIL              ! = 0 …… ein Statuscode

Beispiel:

if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?" 

Ausgabe:

ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2 

Wie gezeigt, gibt der Befehl ls den Statuscode = 2 zurück. Wenn Sie ein gültiges Verzeichnis versuchen, ist der Status Null ( 0 ). Nicht wie in fast allen anderen Sprachen.

Regel # 1 – Machen Sie …

  • TRUE   == 0
  • FALSE! = 0

Wir müssen uns daran erinnern, dass wir Fehlercodes in einer Bash if Anweisung. Ich richte Konstanten ein, oder Sie können Shell-Befehle true oder false verwenden.

TRUE=0 FALSE=1 # valid number function # valNum() { flag=$TRUE if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=$FALSE fi return $flag } # later on ... # if validNum Abc then echo "Lucky number" else echo "Not lucky." fi 

und Ausgabe:

Invalid Number Not lucky. 

Ich schlage jedoch vor, dass Sie “ up-vote „@Gilles, weil seine Antwort die richtige ist. Ich wollte nur die vereinfachende Seite von ePaper auf den Punkt bringen.

Nur eine andere Sache, die test Befehl. Dies sieht folgendermaßen aus:

[[ some-expression ]]; 

Meistens. Und zum Beispiel:

$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0 

Null (0) ist true . Warum? Nun, die Manpage sagt, dass ein einzelnes Argument „ true “ ist, wenn es NICHT NULL ist.

Verweise:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.