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 ]

7voto

Cyker Punkte 8424

In vielen Programmiersprachen ist der Boolesche Typ, oder wird als Untertyp von Ganzzahlen implementiert, wobei true sich wie 1 verhält und false sich wie 0 verhält:

Mathematisch ähnelt die Boolesche Algebra der Ganzzahlarithmetik modulo 2. Daher ist es, wenn eine Sprache keinen nativen Booleschen Typ bereitstellt, die natürlichste und effizienteste Lösung, Ganzzahlen zu verwenden. Dies funktioniert mit fast jeder Sprache. Zum Beispiel kannst du das in Bash tun:

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

man bash:

((Ausdruck))

Der Ausdruck wird gemäß den unten beschriebenen Regeln der ARITHMETISCHEN AUSWERTUNG ausgewertet. Wenn der Wert des Ausdrucks ungleich Null ist, ist der Rückgabewert 0; andernfalls ist der Rückgabewert 1. Dies entspricht genau let "Ausdruck".

6voto

Eric P Punkte 528

In Bezug auf die Syntax handelt es sich um eine einfache Methodik, die ich (am Beispiel) verwende, um Boolesche Logik konsistent und vernünftig zu verwalten:

# Tests
var =
var = ''
var = ""
var = 0
var = 1
var = "abc"
var = abc

if [[ -n "${var}" ]]; then
    echo 'true'
fi
if [[ -z "${var}" ]]; then
    echo 'false'
fi

# Ergebnisse
# var =        # false
# var = ''      # false
# var = ""      # false
# var = 0       # true
# var = 1       # true
# var = "abc"   # true
# var = abc     # true

Wenn die Variable nie deklariert wird, lautet die Antwort: # false

Also wäre ein einfacher Weg, eine Variable auf true zu setzen (unter Verwendung dieser Syntax-Methodik), var = 1; umgekehrt, var = ''.

Referenz:

-n = Wahr, wenn die Länge des var-Strings ungleich Null ist.

-z = Wahr, wenn die Länge des var-Strings Null ist.

5voto

Randyman99 Punkte 305

Bill Parker wird abgewählt, weil seine Definitionen von der normalen Codekonvention abweichen. Normalerweise wird true als 0 definiert und false als nicht null. 1 wird für false funktionieren, genauso wie 9999 und -1. Das Gleiche gilt für Funktionsrückgabewerte - 0 ist Erfolg und alles andere als null ist ein Fehler. Entschuldigung, ich habe noch nicht genug Glaubwürdigkeit, um ihm direkt zu antworten oder zu stimmen.

Bash empfiehlt jetzt, anstelle von einfachen eckigen Klammern doppelte eckige Klammern zu verwenden, und der Link, den Mike Holt gegeben hat, erklärt die Unterschiede in ihrer Funktionsweise. 7.3. Andere Vergleichsoperatoren

Zum Einen ist -eq ein numerischer Operator, weshalb der Code

#**** HINWEIS *** Dies gibt einen Fehler aus *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

Ein Fehler verursacht, da ein Integer-Ausdruck erwartet wird. Dies gilt für beide Parameter, da keiner von ihnen ein Integer-Wert ist. Aber wenn wir doppelte eckige Klammern verwenden, wird kein Fehler ausgegeben, aber es wird ein falscher Wert zurückgegeben (nun ja, in 50% der möglichen Permutationen). Es wird zu [[0 -eq true]] = Erfolg ausgewertet, aber auch zu [[0 -eq false]] = Erfolg, was falsch ist (hmmm... was ist mit diesem Befehl als numerischer Wert?).

#**** HINWEIS *** Dies gibt falsche Ausgabe *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then

Es gibt auch andere Varianten des Bedingungsbausteins, die ebenfalls falsche Ausgaben liefern werden. Grundsätzlich alles (außer der oben aufgeführten Fehlerbedingung), das eine Variable auf einen numerischen Wert setzt und sie mit einem true/false-Befehl vergleicht oder eine Variable auf einen true/false-Befehl setzt und sie mit einem numerischen Wert vergleicht. Auch alles, was eine Variable auf einen true/false-Befehl setzt und einen Vergleich mit -eq durchführt. Vermeiden Sie also -eq für Boolesche Vergleiche und vermeiden Sie die Verwendung von numerischen Werten für Boolesche Vergleiche. Hier ist eine Zusammenfassung der Varianten, die ungültige Ergebnisse liefern:

# Mit Variable als Integer und Auswertung als true/false
# *** Dies gibt eine Fehlerwarnung aus und wird nicht ausgeführt: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

# Mit Variable als Integer und Auswertung als true/false
# *** Diese Anweisungen werden nicht ordnungsgemäß ausgewertet: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

# Mit Variable als true/false-Befehl und Auswertung als true/false
# *** Diese Anweisungen werden nicht ordnungsgemäß ausgewertet: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then

Also, nun dazu, was funktioniert. Verwenden Sie true/false-Befehle sowohl für Ihren Vergleich als auch für Ihre Auswertungen (wie Mike Hunt bemerkte, umgeben Sie sie nicht mit Anführungszeichen). Verwenden Sie dann entweder ein einfaches oder doppeltes Gleichheitszeichen (= oder ==) und entweder einfache oder doppelte eckige Klammern ([ ] oder [[ ]]). Persönlich bevorzuge ich das doppelte Gleichheitszeichen, weil es mich an logische Vergleiche in anderen Programmiersprachen erinnert, und doppelte Anführungszeichen einfach, weil ich gerne tippe. Also funktionieren diese:

# Mit Variable als Integer und Auswertung als true/false
# *** Diese Anweisungen werden ordnungsgemäß funktionieren: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

Das ist alles.

3voto

Frank Nocke Punkte 8618

Mein Rezept für (meine eigene) Idiotie:

# Einstellung ----------------
commonMode=false
if [[ $something == 'COMMON' ]]; then
    commonMode=true
fi

# Verwendung ----------------
if $commonMode; then
    echo 'JA, Common-Modus'
else
    echo 'NEIN, kein Common-Modus'
fi

$commonMode && echo 'commonMode ist EIN ++++++'
$commonMode || echo 'commonMode ist AUS xxxxxx'

1voto

yolenoyer Punkte 7821

Eine andere Möglichkeit, Boolesche Werte zu verwenden, besteht darin, die Leere von Werten zu überprüfen. Dies hat den Vorteil, kürzere Tests zu machen:

first=1  # Ein wahrer Wert
second=   # Ein falscher Wert

[ -n "$first" ]  && echo 'Erste Variable ist wahr'
[ -z "$first" ]  && echo 'Erste Variable ist falsch'
[ -n "$second" ] && echo 'Zweite Variable ist wahr'
[ -z "$second" ] && echo 'Zweite Variable ist falsch'

Ausgabe:

Erste Variable ist wahr
Zweite Variable ist falsch

Hier ist eine alternative Test-Syntax mit bash: [[ -n $one ]]

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