Diese Frage besteht aus zwei Teilen:
(a) Verstehen, was der abgeschnittene Code tut
(b) Verständnis des Unterschieds zwischen Exit-Status und Return-Status im Kontext von bash
.
Hier ist der Code, den ich zu verstehen versuche:
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
Das Ausführen erzeugt False
. Ich kann nicht verstehen, warum das passiert.
Wenn ich das richtig verstehe, passiert hier vielleicht was mit der if
Bedingung:
(a) var=-2
erstellt den Exit-Status 0, da die Zuweisung erfolgreich ist
(b) (( var+=2 ))
addiert 2 zum Wert von var
und der Ausdruck wertet Null aus. Der Exit-Status ist also 1 für diesen Begriff
(c) 0 && 1 erzeugt einen existierenden Status von 0, der dann vom if
Konstrukt verwendet wird
Das if
Konstrukt soll einfach den Exit-Status überprüfen und wenn es Null ist, nimmt es den Then- Pfad. In Schritt (c) oben ist es Null, aber das Skript nimmt immer noch den else- Pfad. Ist das richtig, um das zu verstehen?
Außerdem sehe ich immer wieder, dass verschiedene bash
Texte den Exit-Status und den Return-Status austauschbar verwenden.
Ich bezweifle, dass die var=-2
Zuweisung einen Exit-Status haben würde, da es sich nicht um ein Programm handelt. Aber jede Klarstellung über den Unterschied zwischen zwei wird großartig sein.
#!/bin/bash -x
zu sehen, was passiertman bash
: expression1 && expression2 True, wenn sowohl expression1 als auch expression2 true sind. Ausdruck1 || expression2 True, wenn entweder expression1 oder expression2 true ist. Die && und || Operatoren bewerten expression2 nicht, wenn der Wert von expression1 ausreicht, um den Rückgabewert des gesamten bedingten Ausdrucks zu bestimmen.0 && 1
in der Tat ist1
.i=0; ((i++))
ein fehlgeschlagener Exit-Status, währendi=0; ((++i))
ein erfolgreicher ist. In einem arithmetischen Kontext sind positive ganze Zahlen wahr und Null ist falsch.Antworten:
Das ist:
Dies dient zum Ausführen der zweiten Befehlsliste, wenn die erste Befehlsliste mit einem Exit-Status true / success (Null) zurückgegeben wird, dh wenn der zuletzt ausgeführte Befehl dort mit einem Exit-Status Null zurückgegeben wird.
Im:
Es ist ,
cmd1 && cmd2
wocmd2
nur ausgeführt werden, wenncmd1
erfolgreich ist.Ist normalerweise erfolgreich, solange
$var
es nicht schreibgeschützt ist. Daher wird der((var += 2))
Befehl ausgeführt:Gibt success / true zurück , solange der Ausdruck korrekt ausgewertet wird (kein Syntaxfehler) und das Ergebnis des Ausdrucks ungleich Null ist.
((123))
,((1 + 1))
,((1 == 1))
Return true((0))
,((-2 + 2))
,((2 == -2))
Return false.((4294967296 * 4294967296))
In den meisten Shells wird aufgrund des 64-Bit-Integer-Wrappings false zurückgegebenvar += 2
führt als arithmetischer Ausdruck die Zuweisung durch und löst den zugewiesenen Wert auf, hier 0, daher der falsche Exit-Status.Sie können den Wert, auf dem der Exit-Status basiert, mithilfe der
$((...))
arithmetischen Erweiterungssyntax anzeigen:Oder einer Variablen zuweisen:
$?
enthält den Exit-Status des vorherigen Befehls. Fürif
/then
/else
/fi
bedeutet 0 wahr, alles andere falsch.Die Verwirrung hier kommt von der Tatsache, dass es für arithmetische Ausdrücke umgekehrt ist:
0
bedeutet falsch und alles andere bedeutet wahr (zum Beispiel2 == 2
ist1
während2 < 1
ist0
).Um sich keine Sorgen über den Unterschied zu machen, vergessen Sie einfach
$?
die möglichen Werte. Man denke nur in Bezug auf die boolean wahr / falsch , Erfolg / Misserfolg .Gibt true zurück, wenn
foo
in gefunden wirdfile
.Gibt true zurück, wenn es
$a
dasselbe enthält wie$b
.Geben Sie true zurück, wenn das Ergebnis des arithmetischen Ausdrucks eine Zahl ungleich Null ist.
Es spielt keine Rolle, ob diese wahr / falsch als 0 oder 1 des Exit-Status dieser
grep
/[
Befehle oder((...))
Konstrukte ausgedrückt werden .quelle
((2==2)); echo $? output 0 ((2 > 1)); echo $? output 0
2==2
arithmetische Ausdruck führt zu1
(sieheecho "$((2==2))"
), da das((...))
Konstrukt nicht 0 ist, gibt es true zurück (es gibt den Exit-Status 0 zurück, aber wie gesagt, Sie müssen sich im Allgemeinen keine Gedanken darüber machen, welcher Exit-Code true oder false bedeutet)Da ist der Fehler. 0 && 1 ergibt
1
. Dies ist nicht C oder Java, denken Sie daran. In der Shell ist 0 && 1 das, was Sie bekommen würdentrue && false
.Sie sind austauschbar. Was Sie beachten möchten, ist, dass dies
0
auf Erfolg und nicht0
auf Misserfolg hinweist. Es ist das Gegenteil der meisten Programmiersprachen, in denen0
es falsch und1
wahr ist.quelle
0
von einem Befehl mit einem Exit-Status von unterscheidet0
.Alles funktioniert wie erwartet.
Code Erklärung: -
if var=-2 && (( var+=2 ))
var=-2 => true
Der Wert ist ungleich Null und wird daher als wahr bewertetvar+=2 => false
Der Wert ist Null und wird daher als falsch bewertetdas ist wie
if true && false
Gemäß logischer Berechnung wahr && falsch => falsch
In diesem Fall ist hier unser endgültiger Code
quelle
var=0
,var=-2
als wahr bewerten. Der Wert der Zuordnung spielt hier keine Rolle.var=1$(false)
würde false zurückgeben.((var=0))
würde false zurückgeben,((var=1$(false)))
würde true zurückgeben.