Können wir den bedingten Operator von bash mit Zuweisungsoperatoren nach dem Doppelpunkt verwenden?
Bash-Referenzhandbuch erläutert die arithmetischen Operatoren wie folgt.
- Bedingter Operator
expr ? expr : expr
- Zuweisung
= *= /= %= += -= <<= >>= &= ^= |=
Erstens scheint dieser Code gut zu funktionieren:
a=1; ((a? b=1 : 2 )) #seems to work
Wenn ich jedoch nach :
Zuweisungsoperatoren verwende, wurde der Fehler „Zuweisung versucht, nicht variabel“:
a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error
Warum können wir nur Zuweisungsoperatoren vor dem Doppelpunkt verwenden?
Kommentare
- Es mag Spaß machen, Variablenzuweisungen mit dem bedingten Operator durchzuführen, aber ' würde Ihren Code sehr unlesbar machen. Ich ' würde
((a)) && b=1 || c=1
- @devnull Ich denke, der Code hängt am meisten davon ab, wer sie liest. Es mag zwar wahr sein, was Sie sagen, aber ich ' habe
ternary
-Operatoren indash, zsh, sh
undbash
und alle verhalten sich gleich, obwohl sie nicht von POSIX angegeben wurden. Ihr Beispiel funktioniert meines Wissens nur inbash
undzsh
. Dies ist jedoch POSIX-freundlich:( : ${a?} ) && b=1 || c=1
. Ich finde es auch viel einfacher zu lesen als entwederternary
oder Ihr eigenes Beispiel.
Antwort
Bash analysiert Ihren letzten Befehl als
a=1; (( (a? b=1 : c)=1 ))
, was klarstellen sollte, warum er nicht funktioniert. Stattdessen müssen Sie
a=1; (( a? b=1 : (c=1) ))
Antwort
verwenden. Dies wird als ternary assignment
Ausdruck. Hier „ein bisschen von einer anderen Antwort von mir:
% a=abc % b=abcd % t=10 ; f=5 % echo $((r=${#a}>${#b}?t:f)) ; echo $r > 5 > 5 % echo $((r=${#a}<${#b}?t:f)) ; echo $r > 10 > 10
Sie sehen, wie Sie sagen, dies ist eine bedingte Zuweisungsoperation. Dies hängt von den Bedingungen ab. Die Syntax funktioniert folgendermaßen:
$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign ))
Ich glaube nicht, dass Sie dies richtig verwenden.
Von wikipedia :
?:
wird verwendet wie folgt:
condition ? value_if_true : value_if_false
Die Bedingung wird als boolescher Ausdruck als wahr oder falsch bewertet. Auf der Grundlage der Auswertung der Booleschen Bedingung gibt der gesamte Ausdruck value_if_true zurück, wenn die Bedingung wahr ist, andernfalls value_if_false. Normalerweise müssen die beiden Unterausdrücke value_if_true und value_if_false denselben Typ haben, der den Typ des gesamten Ausdrucks bestimmt. Die Bedeutung dieser Typprüfung liegt in der häufigsten Verwendung des Operators – in bedingten Zuweisungsanweisungen. In dieser Verwendung wird sie wie folgt als Ausdruck auf der rechten Seite einer Zuweisungsanweisung angezeigt:
variable = condition ? value_if_true : value_if_false
Die ähnelt der Funktionsweise von bedingten Ausdrücken (
if-then-else
-Konstrukte) in funktionalen Programmiersprachen wie Scheme, ML und Haskell, da if-then-else eine bildet Ausdruck anstelle einer Anweisung in diesen Sprachen.
Ich denke, Ihr spezifisches Problem hängt damit zusammen:
Wie im if-else-Konstrukt wird nur einer der Ausdrücke „x“ und „y“ ausgewertet.
Wenn Sie den obigen Link zu ternary
-Ausdrücken lesen Sie werden diese Bewertung sehen n ist kurzgeschlossen, daher ist Ihre Zuordnung auf der false -Seite fehlerhaft, weil 1 = true
.
In jedem Fall spielt es keine Rolle zu viel, weil ich nicht glaube, dass dies das tut, was Sie denken.
Antwort
Ternäre Operatoren geben einen Wert zurück, der auf basiert ein Test. Sie werden nicht zum Verzweigen verwendet.
Hier ist eine Möglichkeit, einen pseudo-ternären Operator für Bash zu erhalten (beachten Sie die Back-Ticks):
$result=`[ < condition > ] && echo "true-result" || echo "false-result" `
$ a=
$ c=`[ $a ] && echo 1 || echo 0`
$ echo $c
0
$ a=5
$ c=`[ $a ] && echo 1 || echo 0`
$ echo $c
1