
Diese Frage besteht aus zwei Teilen:
(a) Verstehen, was der ausgeschnittene Code bewirkt
(b) Den Unterschied verstehen zwischenBeendigungsstatusUndRückgabestatusim Kontext von bash
.
Hier ist der Codeausschnitt, den ich zu verstehen versuche:
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
Beim Ausführen wird Folgendes erzeugt False
: Ich kann nicht verstehen, warum das passiert.
Wenn ich das richtig verstehe, passiert möglicherweise Folgendes mit der if
Bedingung:
(a) var=-2
erzeugt den Exit-Status 0, da die Zuweisung erfolgreich war
(b) (( var+=2 ))
addiert 2 zum Wert von var
und der Ausdruck ergibt Null. Der Beendigungsstatus für diesen Term ist also 1
(c) 0 && 1 erzeugt einen Exist-Status von 0, der dann von der if
Konstruktion verwendet wird
Das if
Konstrukt soll einfach den Exit-Status prüfen und wenn dieser Null ist, nimmt es denDannPfad. In Schritt (c) oben ist es Null, aber das Skript nimmt trotzdem denandersPfad. Ist das die richtige Art, das zu verstehen?
Außerdem sehe ich immer wieder verschiedene bash
Texte verwendenBeendigungsstatusUndRückgabestatusaustauschbar.
Ich bezweifle, var=-2
dass die Zuweisung irgendeinen Beendigungsstatus haben würde, da es sich nicht um ein Programm handelt. Aber jede Klarstellung des Unterschieds zwischen beiden wäre großartig.
Antwort1
Das ist:
if
first list of commands
then
second list of commands
else
third list of commands
fi
Das heißt, die zweite Befehlsliste wird ausgeführt, wenn die erste Befehlsliste mit einemWAHR/Erfolg(Null) Exit-Status, d. h. wenn der letzte Ausführungsbefehl dort mit einem Exit-Status von Null zurückkehrt.
In:
var=-2 && ((var += 2))
Es wird nur cmd1 && cmd2
ausgeführt cmd2
, wenn cmd1
es erfolgreich ist.
var=-2
Ist normalerweise erfolgreich, solange der $var
Schreibschutz nicht aktiviert wurde, sodass der ((var += 2))
Befehl ausgeführt wird:
((arithmetic expression))
Kehrt zurückErfolg/WAHRsolange 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))
falsch zurückgeben.((4294967296 * 4294967296))
gibt in den meisten Shells false zurück, da 64-Bit-Integer-Wrapping
var += 2
als arithmetischer Ausdruck, führt die Zuweisung aus und ergibt den zugewiesenen Wert, hier 0, daher dieFALSCHBeendigungsstatus.
Sie können den Wert anzeigen, auf dem der Beendigungsstatus basiert, indem Sie die $((...))
Syntax der arithmetischen Erweiterung verwenden:
$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0
Oder durch Zuweisen zu einer Variablen:
$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0
$?
enthält den Beendigungsstatus des vorherigen Befehls. Bei if
/ then
/ else
/ fi
bedeutet 0 wahr, alles andere bedeutet falsch.
Die Verwirrung rührt hier daher, dass es bei arithmetischen Ausdrücken umgekehrt ist: 0
bedeutet falsch und alles andere bedeutet wahr (z. B. 2 == 2
ist , 1
während 2 < 1
ist 0
).
Um sich keine Sorgen über den Unterschied zu machen, vergessen Sie einfach $?
und seine möglichen Werte. Denken Sie einfach an BoolescheWAHR/FALSCH,Erfolg/Versagen.
grep -q foo file
Gibt „true“ zurück, wenn foo
in gefunden wird file
.
[ "$a" = "$b" ]
Gibt „true“ zurück, wenn $a
dasselbe wie enthält $b
.
((6 * 3 - 12))
((4 == 1))
Gibt „true“ zurück, wenn das Ergebnis des arithmetischen Ausdrucks eine von Null verschiedene Zahl ist.
Es spielt keine Rolle, ob dieseWAHR/FALSCHwerden durch 0 oder 1 als Beendigungsstatus dieser grep
/ [
Befehle oder ((...))
Konstrukte ausgedrückt.
Antwort2
(c) 0 && 1 erzeugt einen Exist-Status von 0, der dann von der
if
Konstruktion verwendet wird
Da liegt der Fehler. 0 && 1 ergibt 1
. Denken Sie daran, das ist nicht C oder Java. In der Shell erhalten Sie 0 && 1 von true && false
.
$ true; echo $?
0
$ false; echo $?
1
$ true && false; echo $?
1
Außerdem sehe ich immer wieder, dass in verschiedenen Bash-Texten die Begriffe „Exit-Status“ und „Return-Status“ synonym verwendet werden.
Sie sind austauschbar. Was Sie im Hinterkopf behalten sollten, ist, dass 0
Erfolg anzeigt und Nicht- 0
Misserfolg anzeigt. Es ist das Gegenteil der meisten Programmiersprachen, wo 0
falsch und 1
wahr ist.
Antwort3
Alles funktioniert wie erwartet.
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
Codeerklärung: -
if var=-2 && (( var+=2 ))
var=-2 => true
Der Wert ist ungleich Null und wird daher als wahr ausgewertet.
var+=2 => false
Der Wert ist Null und wird daher als „false“ ausgewertet.
das ist wie
if true && false
Gemäß logischer Berechnungwahr && falsch => falsch
In diesem Fall ist hier unser endgültiger Code
if (false)
then
echo "True"
else
echo "False"
fi