Putem folosi operatorul condițional bash cu operatori de atribuire după colon?
Manual de referință Bash explică operatorii aritmetici după cum urmează.
- operator condiționat
expr ? expr : expr
- atribuire
= *= /= %= += -= <<= >>= &= ^= |=
În primul rând, acest cod pare să funcționeze bine:
a=1; ((a? b=1 : 2 )) #seems to work
Dar când folosesc operatori de atribuire după :
, am primit o eroare de „încercare de atribuire la variabilă”:
a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error
De ce putem folosi numai operatori de atribuire înainte de colon?
Comentarii
Răspuns
Bash analizează ultima comandă ca
a=1; (( (a? b=1 : c)=1 ))
care ar trebui să clarifice de ce nu funcționează. În schimb, trebuie să utilizați
a=1; (( a? b=1 : (c=1) ))
Răspuns
Aceasta se numește ternary assignment
expresie. Iată „un pic dintr-un alt răspuns al meu:
% 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
Vedeți, după cum spuneți, aceasta este o operațiune de atribuire condițională . Depinde de condiții. Sintaxa funcționează astfel:
$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign ))
Nu cred că o folosești corect.
De la wikipedia :
?:
după cum urmează:
condition ? value_if_true : value_if_false
Condiția este evaluată adevărată sau falsă ca expresie booleană. Pe baza evaluării condiției booleene, întreaga expresie returnează value_if_true dacă condiția este adevărată, dar value_if_false altfel. De obicei, cele două sub-expresii value_if_true și value_if_false trebuie să aibă același tip, care determină tipul întregii expresii. Importanța acestei verificări de tip constă în cea mai obișnuită utilizare a operatorului – în instrucțiunile de atribuire condiționată. În această utilizare apare ca o expresie în partea dreaptă a unei instrucțiuni de atribuire, după cum urmează:
variable = condition ? value_if_true : value_if_false
?:
operatorul este similar cu modul în care expresiile condiționale (if-then-else
construiesc) funcționează în limbaje funcționale de programare, cum ar fi Scheme, ML și Haskell, deoarece if-then-else formează un expresie în loc de o afirmație în aceste limbi.
Cred că problema dvs. specifică este legată de aceasta:
La fel ca în construcția if-else se evaluează doar una dintre expresiile „x” și „y”.
Dacă citiți linkul de mai sus pe expresiile ternary
vei vedea acea evaluare n este scurtcircuitat, deci atribuirea dvs. pe false erori laterale deoarece 1 = true
.
În orice caz, nu contează prea mult pentru că nu cred că acest lucru face ceea ce crezi că face.
Răspuns
Operatorii ternari returnează o valoare bazată pe un test. Nu sunt utilizate pentru ramificare.
Iată o modalitate de a obține un operator pseudo-ternar pentru bash (rețineți căpușele):
$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
((a)) && b=1 || c=1
ternary
operatori îndash, zsh, sh
șibash
și se comportă la fel, în ciuda faptului că nu au fost specificate de POSIX. Exemplul dvs. funcționează numai înbash
șizsh
din câte știu. Cu toate acestea, acesta este prietenos cu POSIX:( : ${a?} ) && b=1 || c=1
. De asemenea, mi se pare mult mai ușor de citit decâtternary
sau propriul exemplu.