Ich möchte eine Bash-Funktion schreiben, die prüft, ob eine Datei bestimmte Eigenschaften hat und true oder false zurückgibt. Dann kann ich es in meinen Skripten im "if" verwenden. Aber was soll ich zurückgeben?
function myfun(){ ... return 0; else return 1; fi;}
dann benutze ich es so:
if myfun filename.txt; then ...
Das funktioniert natürlich nicht. Wie kann dies erreicht werden?
function
myfun() {...}
if
ist der Null-Exit-Status vonmyfun
: Wennmyfun
Exits mit0
,then ...
wird ausgeführt; wenn es etwas andereselse ...
ist, wird ausgeführt.function
Schlüsselwort ist ein Bashismus und verursacht in einigen anderen Shells Syntaxfehler. Grundsätzlich ist es entweder unnötig oder verboten. Warum also? Es ist nicht einmal als Grep-Ziel nützlich, da es möglicherweise nicht vorhanden ist (()
stattdessen Grep für ).Antworten:
Verwenden Sie 0 für wahr und 1 für falsch.
Stichprobe:
Bearbeiten
Nach dem Kommentar von @ amichair sind diese ebenfalls möglich
quelle
[ -d "$1" ]
.Warum sollte es dich interessieren, was ich sage, obwohl es eine Antwort von mehr als 250 Stimmen gibt?
Es ist nicht das
0 = true
und1 = false
. Es ist: Null bedeutet kein Fehler (Erfolg) und Nicht-Null bedeutet Fehler (vom Typ N) .Während die ausgewählte Antwort technisch "wahr" ist, geben Sie bitte nicht
return 1
** in Ihren Code für falsch ein . Es wird mehrere unglückliche Nebenwirkungen haben.Lerne etwas Bash
Das Bash-Handbuch sagt (Hervorhebung von mir)
Daher müssen wir NIEMALS 0 und 1 verwenden, um Wahr und Falsch anzuzeigen. Die Tatsache, dass sie dies tun, ist im Wesentlichen triviales Wissen, das nur zum Debuggen von Code, zum Befragen von Fragen und zum Umblasen von Neulingen nützlich ist.
Das Bash-Handbuch sagt auch
Das Bash-Handbuch sagt auch
Whoa, warte. Pipeline? Wenden wir uns noch einmal dem Bash-Handbuch zu.
Ja. Sie sagten, 1 Befehl sei eine Pipeline. Daher sagen alle drei Zitate dasselbe.
$?
sagt dir, was zuletzt passiert ist.Meine Antwort
Während @Kambus demonstrierte, dass mit einer so einfachen Funktion überhaupt keine
return
benötigt wird. Ich denke, es war unrealistisch einfach im Vergleich zu den Bedürfnissen der meisten Leute, die dies lesen werden.Warum
return
?Wenn eine Funktion den Exit-Status ihres letzten Befehls zurückgibt, warum
return
überhaupt verwenden? Weil dadurch eine Funktion nicht mehr ausgeführt wird.Stoppen Sie die Ausführung unter mehreren Bedingungen
Was wir hier haben ist ...
Zeile
04
ist eine explizite [-ish] Rückgabe true, da die RHS von&&
nur ausgeführt wird, wenn die LHS true warZeile
09
gibt entweder wahr oder falsch zurück, was dem Status der Zeile entspricht08
Zeile
13
gibt wegen Zeile falsch zurück12
(Ja, dies kann abgespielt werden, aber das gesamte Beispiel ist erfunden.)
Ein weiteres häufiges Muster
Beachten Sie, wie das Setzen einer
status
Variablen die Bedeutung von entmystifiziert$?
. (Natürlich wissen Sie, was$?
bedeutet, aber jemand, der weniger kenntnisreich ist als Sie, wird es eines Tages googeln müssen. Wenn Ihr Code keinen Hochfrequenzhandel betreibt, zeigen Sie etwas Liebe , setzen Sie die Variable.) Aber das eigentliche Mitnehmen ist das "wenn" Nicht vorhandener Status "oder umgekehrt" wenn Exit-Status "kann laut vorgelesen und deren Bedeutung erklärt werden. Allerdings kann das letzte ein wenig zu ehrgeizig sein , weil das Wort zu sehen ,exit
könnten Sie es denken das Skript wird beendet, wenn es in Wirklichkeit die verlässt$(...)
Subshell.** Wenn Sie unbedingt darauf bestehen,
return 1
für false zu verwenden, empfehle ich Ihnen,return 255
stattdessen mindestens zu verwenden . Dies führt dazu, dass Sie oder ein anderer Entwickler, der Ihren Code pflegen muss, die Frage stellen: "Warum ist das 255?" Dann werden sie zumindest aufpassen und eine bessere Chance haben, einen Fehler zu vermeiden.quelle
if
Erfolg, mach das,else
mach das." Erfolg bei was? Könnte für wahr / falsch überprüft werden, könnte für eine Zeichenfolge, integer, Datei, Verzeichnis, Schreibrechte, glob, regex, grep, oder einen anderen Befehl wird überprüft , das ist vorbehaltlich Ausfälle .true
undfalse
Befehle. Das heißt, das Schlüsselwort ergibttrue
buchstäblich einen 0-Statuscode. Darüber hinaus arbeiten If-Then-Anweisungen von Natur aus mit Booleschen Werten und nicht mit Erfolgscodes. Wenn während einer booleschen Operation ein Fehler auftritt, sollte er nicht true oder false zurückgeben, sondern lediglich die Ausführung unterbrechen. Andernfalls erhalten Sie falsch positive Ergebnisse (Wortspiel).return 1
vermieden werden sollte. Angenommen, ich habe einevalidate
Funktion, die ich für sinnvoll halte,return 1
wenn die Validierung fehlschlägt. Dies ist schließlich ein Grund, die Ausführung eines Skripts zu stoppen, wenn es nicht ordnungsgemäß behandelt wird (z. B. bei Verwendungset -e
).return 1
ist gültig. Mein Anliegen sind alle Kommentare hier, die besagen: "0 = wahr 1 = falsch ist [negatives Wort einfügen]". Diese Leute werden wahrscheinlich eines Tages Ihren Code lesen. Für sie sollte das Sehenreturn 255
(oder 42 oder sogar 2) ihnen helfen, mehr darüber nachzudenken und es nicht als „wahr“ zu verwechseln.set -e
werde es immer noch fangen.quelle
Seien Sie vorsichtig, wenn Sie das Verzeichnis nur mit der Option -d überprüfen!
Wenn die Variable $ 1 leer ist, ist die Prüfung weiterhin erfolgreich. Stellen Sie sicher, dass die Variable nicht leer ist.
quelle
$1
("$1"
) ein korrektes Anführungszeichen hinzufügen . Das[[ -d "$1" ]]
würde fehlschlagen, da dies""
kein Verzeichnis ist.Ich bin auf einen Punkt gestoßen (noch nicht explizit erwähnt?), Über den ich gestolpert bin. Das heißt, nicht , wie man das Rück die boolean, sondern wie man es richtig zu bewerten!
Ich habe versucht zu sagen
if [ myfunc ]; then ...
, aber das ist einfach falsch. Sie dürfen die Klammern nicht verwenden!if myfunc; then ...
ist der Weg, es zu tun.Wie bei @Bruno und anderen wiederholt,
true
undfalse
sind Befehle , keine Werte! Dies ist sehr wichtig, um Boolesche Werte in Shell-Skripten zu verstehen.In diesem Beitrag habe ich boolesche Variablen erklärt und demonstriert : https://stackoverflow.com/a/55174008/3220983 . Ich empfehle dringend, dies zu überprüfen, da es so eng miteinander verbunden ist.
Hier werde ich einige Beispiele für die Rückgabe und Auswertung von Booleschen Werten aus Funktionen geben:
Dies:
Erzeugt keine Echoausgabe. (dh
false
gibt false zurück)Produziert:
(dh
true
gibt true zurück)Und
Produziert:
Weil 0 (dh wahr) implizit zurückgegeben wurde .
Das hat mich vermasselt ...
Produziert:
UND
AUCH produziert:
Die Verwendung der Klammern hier ergab ein falsches Positiv ! (Ich schließe daraus, dass das "äußere" Befehlsergebnis 0 ist.)
Die wichtigste Auswirkung meines Beitrags ist: Verwenden Sie keine Klammern, um eine boolesche Funktion (oder Variable) auszuwerten, wie Sie es für eine typische Gleichheitsprüfung tun würden, z
if [ x -eq 1 ]; then...
.quelle
Verwenden Sie die Befehle
true
oderfalse
unmittelbar vor Ihremreturn
, dannreturn
ohne Parameter. Der verwendetreturn
automatisch den Wert Ihres letzten Befehls.Das Bereitstellen von Argumenten für
return
ist inkonsistent, typspezifisch und fehleranfällig, wenn Sie nicht 1 oder 0 verwenden. Wie bereits in früheren Kommentaren erwähnt, ist die Verwendung von 1 oder 0 hier nicht der richtige Weg, um sich dieser Funktion zu nähern.Ausgabe:
quelle
Es könnte funktionieren, wenn Sie dies
function myfun(){ ... return 0; else return 1; fi;}
wie folgt umschreibenfunction myfun(){ ... return; else false; fi;}
. Das heißt, wenn diesfalse
die letzte Anweisung in der Funktion ist, erhalten Sie ein falsches Ergebnis für die gesamte Funktion,return
unterbrechen jedoch die Funktion trotzdem mit dem wahren Ergebnis. Ich glaube, das gilt zumindest für meinen Bash-Dolmetscher.quelle
Ich fand die kürzeste Form zum Testen der Funktionsausgabe einfach
quelle
Aus Gründen der Lesbarkeit des Codes sollte meines Erachtens die Rückgabe von true / false:
return
gefolgt von einem anderen Schlüsselwort (true
oderfalse
)Meine Lösung ist
return $(true)
oderreturn $(false)
wie gezeigt:quelle
Nach @Bruno Bronosky und @mrteatime schlage ich vor, dass Sie Ihre boolesche Rückgabe einfach "rückwärts" schreiben. Das ist was ich meine:
Dadurch entfällt die hässliche zweizeilige Anforderung für jede return-Anweisung.
quelle