Grundlegendes zu booleschen Operatoren im Bash-Skript [Duplikat]

Diese Frage hat hier bereits Antworten :

Antwort

Die Variable $phone_missing ist eine Zeichenfolge, die zufällig false enthält. Eine nicht leere Zeichenfolge ergibt true. Siehe auch http://www.linuxintro.org/wiki/Babe#empty_strings

Kommentare

  • Ah in Ordnung. Ich hätte diese Variable als boolesch deklariert (zumindest nicht mit dem Deklarationswort), aber die Aschekonsole ließ mich nicht '. Ich möchte auch ' Strings nicht vergleichen. Wie wird das richtig gemacht?
  • stackoverflow.com/questions/2953646/… , Aber Vorsicht: Dieser Typ führt eine Zeichenfolgenvariable aus und sowohl falsch als auch wahr sind Unix-Befehle.

Antwort

Ich verwende oft „true“ und „false“, da es sich auch um Befehle handelt, die lediglich Erfolg bzw. Misserfolg zurückgeben. Dann können Sie

if "$phone_missing"; then ... 

Antwort

Hier ist eine Möglichkeit Dies unter Beibehaltung der True / False-Werte.

 phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is true." fi  

Die doppelten Anführungszeichen $phone_missing soll vor dem Fall schützen, dass die Variable phone_missing überhaupt nicht definiert ist. Eine andere gebräuchliche Redewendung, um dies zu verhindern, ist [ x$phone_missing != xfalse ], aber die Anführungszeichen erscheinen mir natürlicher.

Der Hinweis befindet sich auf der Hilfeseite bash für test:

 STRING True if string is not empty. ... ! EXPR True if expr is false. 

Im Grunde genommen ist [ $foo ] wahr, wenn $foo nicht leer ist. Nicht wahr oder falsch, nur nicht leer. [ ! $foo ] ist wahr, wenn $ foo leer oder undefiniert ist.

Sie können Ihren Code jederzeit so ändern, dass phone_missing auf non gesetzt wird -leerer Wert e, was wahr bedeutet. Wenn phone_missing nicht gesetzt ist (oder leer ist – phone_missing=""), ist dies falsch. Andernfalls sollten Sie die Operatoren zum Testen von Zeichenfolgen verwenden (= und !=).

Das andere kleine Problem ist die Zuordnung. Sie haben es als $phone_missing=true, während es phone_missing=true (kein Dollarzeichen) sein sollte.

Entschuldigung, wenn dies der Fall ist ein bisschen dicht, es liegt daran, dass ich bin. Es war ein langer Tag. 🙂

Antwort

Andere Antworten gaben Ihnen eine Lösung, aber ich werde erklären, was mit dem ursprünglichen Denken falsch war.

Bash-Variablen haben keine Typen, daher gibt es keine boolesche Variable oder einen Wert wie true oder false. Grundsätzlich sind alle Bash-Variablen nur Zeichenfolgen.

Wenn Sie eine Variable / Zeichenfolge in Bash testen, ohne den Testtyp anzugeben (-n oder ) wird standardmäßig ein -n -Test (Zeichenfolge ungleich Null) verwendet.

Also [ "$var" ] entspricht [ -n "$var" ]. Solange $var mindestens 1 Zeichen enthält, wurde es als wahr ausgewertet.

Da Sie den Ausdruck negiert haben, [ ! "$var" ] entspricht [ ! -n "$var" ]. Wenn also $var mindestens 1 Zeichen enthält, ist der Ausdruck falsch.

Da false (was gerecht ist) eine Zeichenfolge) enthält 5 Zeichen, der Ausdruck ist falsch. Wenn es keine Rolle spielt, welche Zeichenfolge Sie phone_missing auf (true, 0, 1) setzen, lautet der Ausdruck immer false, weil phone_missing eine Länge ungleich Null ist. Die einzige Möglichkeit, true zu erstellen, ist phone_missing="", da dies die Länge Null ist.

Antwort

Verwenden Sie keine Zeichenfolge für Boolesche Werte. Verwenden Sie eine Ganzzahl.

Eingabe:

val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false" 

Ausgabe:

true false 

Quelle :

((Ausdruck))

Der Ausdruck wird gemäß den unten unter ARITHMETISCHE BEWERTUNG beschriebenen Regeln ausgewertet. Wenn der Wert des Ausdrucks nicht Null ist, ist der Rückgabestatus 0; Andernfalls lautet der Rückgabestatus 1. Dies entspricht genau dem Ausdruck „Ausdruck“.

Antwort

Ich hätte dies als Kommentar zur Unterstützung von James getan Ko hatte aber nicht den Repräsentanten, um zu kommentieren oder öffentlich abzustimmen.

Das Problem hierbei ist, dass die Klammern [] die Notation für einen Vergleichstest wie Wert oder Zeichenfolgengleichheit sind.

Die Wahrhaftigkeit der Zeichenfolge in Bash für eine leere Zeichenfolge lautet "" (leere Zeichenfolge) wird als falsch (Rückgabewert 1) und jede nicht leere Zeichenfolge als „falsch“ „wahr ausgewertet „oder“ bob „s dein Onkel“ wird als wahr ausgewertet (Rückgabewert 0).

Sie können sich dies selbst beweisen mit:

 if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

Die obige $? ist eine spezielle Variable, die den Status zum Beenden der letzten Befehle enthält (0 Erfolg und eine beliebige> 0 für Fehlercode) und true is 0. Sie können "foo" durch alles ersetzen, was Sie möchten. Das Ergebnis ist das gleiche, außer wenn Sie es durch eine leere Zeichenfolge ersetzen. "" oder "" In diesem Fall wird die else-Bedingung ausgewertet und false is 1 ausgegeben.

Bei Verwendung von [ ] Klammern die interne Anweisung wie! $ phone_missing wird ausgewertet und geben dann ein 0 für true oder 1 für false an die if-Steuerung zurück l Aussage. Da die Klammer Zeichenfolgen- und Wertevergleiche auswertet, wird $ phone_missing zuerst auf die nicht leere Zeichenfolge „false“ erweitert, die von [] als nicht leere Zeichenfolge (oder true) und dann als! Invertiert das Ergebnis, was dazu führt, dass die if-Anweisung einen falschen Wert (oder Rückgabewert 1) erhält, und überspringt den Bedingungskörper, der die else-Anweisung ausführt, falls vorhanden.

Wie James Ko sagte, wäre die Notation, einfach die zu übergeben Variable, die Ihren „Booleschen Wert“ für die if-Steueranweisung enthält. Beachten Sie , dass in bash ein boolesches wahr und falsch klein geschrieben werden muss wie in: bool_true = true bool_false = false Jeder andere Fall wird als Zeichenfolgen und nicht als boolesch bewerten.

Wenn Sie also Ihr Beispiel und die Antwort von James Ko verwenden, lautet dies:

phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi 

oder als ich bevorzugen Sie die Lesbarkeit (syntaktisch gleich und James Ko „s)

phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi 

Andere Antworten wie von Alexios überprüfen buchstäblich den Inhalt der Zeichenfolge. Damit würde eine der folgenden Aussagen zu false führen:

phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == Bobs_your_uncle ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi 

Antwort

Die korrekte Syntax lautet if ! $bool; then [statements]; fi.

Beispiel:

bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

Ausgabe: This is correct!

Kommentare

  • Ihre Antwort enthält einen Kern der Wahrheit, aber ohne Erklärung verursacht sie mehr Verwirrung als es Abhilfe schafft. Es ist auch kaum mehr als eine Wiederholung einer der vorherigen Antworten. Wenn Sie nicht möchten, dass Ihre Antwort entfernt wird, erklären Sie, warum sie richtig ist.

Schreibe einen Kommentar

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