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, shundbashund alle verhalten sich gleich, obwohl sie nicht von POSIX angegeben wurden. Ihr Beispiel funktioniert meines Wissens nur inbashundzsh. Dies ist jedoch POSIX-freundlich:( : ${a?} ) && b=1 || c=1. Ich finde es auch viel einfacher zu lesen als entwederternaryoder 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_falseDie 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_falseDie ä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