Possiamo usare loperatore condizionale bash “con operatori di assegnazione dopo i due punti?
Manuale di riferimento di Bash spiega gli operatori aritmetici come segue.
- Operatore condizionale
expr ? expr : expr
- assignment
= *= /= %= += -= <<= >>= &= ^= |=
Innanzitutto, questo codice sembra funzionare bene:
a=1; ((a? b=1 : 2 )) #seems to work
Ma quando uso operatori di assegnazione dopo :
, ho ricevuto lerrore “tentativo di assegnazione a non variabile”:
a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error
Perché possiamo utilizzare solo operatori di assegnazione prima dei due punti?
Commenti
Rispondi
Bash analizza il tuo ultimo comando come
a=1; (( (a? b=1 : c)=1 ))
, il che dovrebbe chiarire perché non funziona. Invece devi usare
a=1; (( a? b=1 : (c=1) ))
Answer
Questo è chiamato ternary assignment
espressione. Ecco “un po da unaltra mia risposta:
% 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
Vedi, come dici tu, questa è unoperazione di assegnazione condizionale . Dipende dalle condizioni. La sintassi funziona in questo modo:
$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign ))
Non credo che tu lo stia usando correttamente.
Da wikipedia :
?:
è utilizzato come segue:
condition ? value_if_true : value_if_false
La condizione viene valutata come vera o falsa come espressione booleana. Sulla base della valutazione della condizione booleana, lintera espressione restituisce value_if_true se condition è true, ma value_if_false altrimenti. Di solito le due sottoespressioni value_if_true e value_if_false devono avere lo stesso tipo, che determina il tipo dellintera espressione. Limportanza di questo controllo del tipo risiede nelluso più comune delloperatore: nelle istruzioni di assegnazione condizionale. In questo utilizzo appare come unespressione sul lato destro di unistruzione di assegnazione, come segue:
variable = condition ? value_if_true : value_if_false
?:
è simile al modo in cui le espressioni condizionali (if-then-else
costrutti) funzionano nei linguaggi di programmazione funzionale, come Scheme, ML e Haskell, poiché if-then-else forma un espressione invece di una dichiarazione in quelle lingue.
Penso che il tuo problema specifico sia correlato a questo:
Come nel costrutto if-else viene valutata solo una delle espressioni “x” e “y”.
Se leggi il link sopra nelle espressioni ternary
vedrai quella valutazione n è in cortocircuito, quindi la tua assegnazione sul lato falso si sbaglia perché 1 = true
.
In ogni caso, non importa troppo perché non credo che questo faccia quello che pensi.
Answer
Gli operatori ternari restituiscono un valore basato su un test. Non sono usati per la ramificazione.
Ecco un modo per ottenere un operatore pseudo-ternario per bash (notare i segni di graduazione indietro):
$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 indash, zsh, sh
ebash
e si comportano tutti allo stesso modo, nonostante non siano specificati da POSIX. Il tuo esempio funziona solo inbash
ezsh
per quanto ne so. Tuttavia, questo è compatibile con POSIX:( : ${a?} ) && b=1 || c=1
. Trovo anche molto più facile da leggere rispetto aternary
o al tuo esempio.