Bash ' s operatore condizionale e assegnazione

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

  • Potrebbe essere divertente eseguire assegnazioni di variabili utilizzando loperatore condizionale, ma ' d rende il tuo codice altamente illeggibile. ' preferisco ((a)) && b=1 || c=1
  • @devnull Penso che il codice dipende soprattutto da chi lo legge. Tuttavia, potrebbe essere vero quello che dici, ma io ' ho testato ternary operatori in dash, zsh, sh e bash e si comportano tutti allo stesso modo, nonostante non siano specificati da POSIX. Il tuo esempio funziona solo in bash e zsh per quanto ne so. Tuttavia, questo è compatibile con POSIX: ( : ${a?} ) && b=1 || c=1. Trovo anche molto più facile da leggere rispetto a ternary o al tuo esempio.

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *