1291 Stimmen

Wie kann ich boolesche Variablen in einem Shell-Skript deklarieren und verwenden?

Ich habe versucht, eine Boolesche Variable in einem Shellskript unter Verwendung der folgenden Syntax zu deklarieren:

variable=$false

variable=$true

Ist das richtig? Außerdem, wenn ich diese Variable aktualisieren wollte, würde ich die gleiche Syntax verwenden? Ist schließlich die folgende Syntax zur Verwendung von Booleschen Variablen als Ausdrücke korrekt?

if [ $variable ]

if [ !$variable ]

24voto

Hbar Punkte 433

Früher, als wir nur sh hatten, wurden Booleans durch eine Konvention des test-Programms behandelt, bei dem test einen falschen Exit-Status zurückgibt, wenn es ohne Argumente ausgeführt wird.

Dies ermöglicht es, eine Variable, die nicht festgelegt ist, als falsch zu betrachten und eine Variable, die auf einen Wert gesetzt ist, als wahr. Heutzutage ist test ein internes Befehl in Bash und ist allgemein bekannt durch seinen einzeiligen Alias [ (oder als ausführbare Datei, die in Shells verwendet wird, die es nicht haben, wie dolmen bemerkt):

FLAG="up or "

if [ "$FLAG" ] ; then
    echo 'Ist wahr'
else
    echo 'Ist falsch'
fi

# FLAG nicht festgelegt
#    funktioniert auch
FLAG=

if [ "$FLAG" ] ; then
    echo 'Bleibt wahr'
else
    echo 'Wurde falsch'
fi

Aufgrund von Zitierkonventionen bevorzugen Skriptautoren den Einsatz des Kompound-Befehls [[, der test nachahmt, aber eine schönere Syntax hat: Variablen mit Leerzeichen müssen nicht zitiert werden; man kann && und || als logische Operatoren mit eigenartiger Reihenfolge verwenden, und es gibt keine POSIX-Beschränkungen hinsichtlich der Anzahl der Bedingungen.

Zum Beispiel, um festzustellen, ob FLAG festgelegt ist und COUNT eine Zahl größer als 1 ist:

FLAG="u p"
COUNT=3

if [[ $FLAG  && $COUNT -gt '1' ]] ; then
    echo 'Flag ist aktiv, Count größer als 1'
else
    echo 'Nein'
fi

Dies kann verwirrend werden, wenn Leerzeichen, null-längige Zeichenfolgen und leere Variablen benötigt werden und auch, wenn Ihr Skript mit mehreren Shells zusammenarbeiten muss.

14voto

sjsam Punkte 20706

Wie kann ich boolesche Variablen in einem Shell-Skript deklarieren und verwenden?

Im Gegensatz zu vielen anderen Programmiersprachen trennt Bash ihre Variablen nicht nach "Typen". [1]

Die Antwort ist also recht klar. Es gibt keine boolesche Variable in Bash.

Dennoch:

Mit einer declare-Anweisung können wir die Wertzuweisung auf Variablen beschränken. [2]

#!/bin/bash
declare -ir BOOL=(0 1) # Denken Sie daran, BOOL kann erst gelöscht werden, wenn diese Shell beendet ist
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}

# Gleichbedeutend mit declare -ir false=0 true=1
((true)) && echo "Wahr"
((false)) && echo "Falsch"
((!true)) && echo "Nicht wahr"
((!false)) && echo "Nicht falsch"

Die Option r in declare und readonly wird verwendet, um explizit anzugeben, dass die Variablen schreibgeschützt sind. Ich hoffe, der Zweck ist klar.

13voto

Pyrolistical Punkte 26854

Statt ein Boolean zu fälschen und eine Falle für zukünftige Leser zu hinterlassen, warum nicht einfach einen besseren Wert als true und false verwenden?

Zum Beispiel:

build_state=erfolg
if etwas-schreckliches; dann
  build_state=fehlgeschlagen
fi

if [[ "$build_state" == erfolg ]]; dann
  echo nach Hause gehen; du bist fertig
sonst
  echo dein Kopf brennt; lauf im Kreis herum
fi

11voto

BuvinJ Punkte 8973

Meine Feststellungen und Vorschläge unterscheiden sich ein wenig von den anderen Beiträgen. Ich fand heraus, dass ich "Booleans" im Grunde genauso verwenden konnte wie in jeder "normalen" Sprache, ohne das vorgeschlagene "Hürdenübersteigen"...

Es ist kein Bedarf an [] oder expliziten Zeichenfolgenvergleichen erforderlich... Ich habe mehrere Linux-Distributionen ausprobiert. Ich habe Bash, Dash und BusyBox getestet. Die Ergebnisse waren immer gleich. Ich bin mir nicht sicher, über was die ursprünglichen am meisten bewerteten Beiträge sprechen. Vielleicht haben sich die Zeiten geändert und das ist alles was es ist?

Wenn Sie eine Variable auf true setzen, wird sie anschließend als "affirmativ" innerhalb einer Bedingung ausgewertet. Setzen Sie sie auf falseund sie wird als "negativ" ausgewertet. Sehr unkompliziert! Der einzige Vorbehalt ist, dass eine undefinierte Variable ebenfalls wie true ausgewertet wird! Es wäre schön, wenn es das Gegenteil tun würde (wie es in den meisten Sprachen der Fall wäre), aber das ist der Trick - Sie müssen Ihre Booleans einfach explizit auf true oder false initialisieren.

Warum funktioniert es so? Die Antwort ist zweigeteilt. A) true/false in einer Shell bedeutet wirklich "kein Fehler" vs. "Fehler" (d.h. 0 vs. alles andere). B) true/false sind keine Werte - sondern vielmehr Anweisungen in der Shell-Skripting! In Bezug auf den zweiten Punkt setzt das Ausführen von true oder false in einer eigenen Zeile den Rückgabewert für den Block, in dem Sie sich befinden, auf diesen Wert, d.h. false ist eine Erklärung für "Fehler aufgetreten", wobei true das "bereinigt". Wenn Sie es mit einer Zuweisung an eine Variable verwenden, "gibt" es das in die Variable zurück. Eine undefinierte Variable wird in einer Bedingung wie true ausgewertet, weil das auch gleichermaßen 0 oder "kein Fehler aufgetreten" repräsentiert.

Sehen Sie sich die Beispielsbashzeilen und Ergebnisse unten an. Testen Sie es selbst, wenn Sie möchten, um es zu bestätigen...

#!/bin/sh

# Noch nicht definiert...
echo "wenn auf ${myBool} gesetzt"
if ${myBool}; then echo "es wird als wahr ausgewertet"; else echo "es wird als falsch ausgewertet"; fi;

myBool=true
echo "wenn auf ${myBool} gesetzt"
if ${myBool}; then echo "es wird als wahr ausgewertet"; else echo "es wird als falsch ausgewertet"; fi;

myBool=false
echo "wenn auf ${myBool} gesetzt"
if ${myBool}; then echo "es wird als wahr ausgewertet"; else echo "es wird als falsch ausgewertet"; fi;

Erzeugt

wenn auf
es wird als wahr ausgewertet
wenn auf true gesetzt
es wird als wahr ausgewertet
wenn auf false gesetzt
es wird als falsch ausgewertet

8voto

LinuxSecurityFreak Punkte 2308

POSIX (Portable Operating System Interface)

Ich vermisse hier den Schlüsselpunkt, nämlich die Portabilität. Deshalb enthält mein Header POSIX in sich.

Grundsätzlich sind alle gewählten Antworten richtig, mit der Ausnahme, dass sie zu stark auf Bash spezifisch sind.

Im Grunde möchte ich nur mehr Informationen zur Portabilität hinzufügen.


  1. [ und ] Klammern wie in [ "$var" = true ] sind nicht notwendig, und Sie können sie weglassen und das test-Kommando direkt verwenden:

    test "$var" = true && yourCodeIfTrue || yourCodeIfFalse

    Wichtiger Hinweis: Ich empfehle dies nicht mehr, da es langsam veraltet ist und schwieriger wird, mehrere Anweisungen zu kombinieren.

  2. Stellen Sie sich vor, was die Wörter true und false für die Shell bedeuten, testen Sie es selbst:

    echo $(( true ))
    0
    echo $(( false ))
    1

    Aber mit Anführungszeichen:

    echo $(( "true" ))
    bash: "true": Syntaxfehler: Operand erwartet (Fehler-Token ist ""true"")
    sh (dash): sh: 1: arithmetischer Ausdruck: Primär erwartet: ""true""

    Das gleiche gilt für:

    echo $(( "false" ))

    Die Shell kann es nur als Zeichenfolge interpretieren. Ich hoffe, Sie haben verstanden, wie gut es ist, das richtige Schlüsselwort ohne Anführungszeichen zu verwenden.

    Aber das hat niemand in früheren Antworten gesagt.

  3. Was bedeutet das? Nun, mehrere Dinge.

    • Sie sollten sich daran gewöhnen, dass die booleschen Schlüsselwörter tatsächlich wie Zahlen behandelt werden, das heißt, true = 0 and false = 1, denken Sie daran, dass alle Nicht-Null-Werte wie false behandelt werden.

    • Da sie als Zahlen behandelt werden, sollten Sie sie auch so behandeln, d.h. wenn Sie eine Variable definieren, sagen:

      var_bool=true
      echo "$var_bool"
       true

      können Sie einen gegenteiligen Wert davon erstellen mit:

      var_bool=$(( 1 - $var_bool ))  # das gleiche wie $(( ! $var_bool ))
      echo "$var_bool"
      1

    Wie Sie selbst sehen können, gibt die Shell beim ersten Mal, wenn Sie es verwenden, die Zeichenfolge true aus, danach funktioniert alles jedoch über die Zahl 0, die für true steht, oder die Zahl 1, die für false steht.


Zuletzt, was Sie mit all diesen Informationen tun sollten

  • Erstens wäre es eine gute Gewohnheit, 0 anstelle von true zuzuweisen; 1 anstelle von false.

  • Zweitens wäre es eine gute Gewohnheit, zu testen, ob die Variable gleich / ungleich null ist:

    if [ "$var_bool" -eq 0 ]; then
         yourCodeIfTrue
    else
         yourCodeIfFalse
    fi

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