Bash ' s villkorliga operatör och tilldelning

Kan vi använda bashs villkorliga operatör med tilldelningsoperatorer efter kolon?

Bash-referenshandbok förklarar aritmetiska operatorer enligt följande.

  • villkorlig operator expr ? expr : expr
  • uppgift = *= /= %= += -= <<= >>= &= ^= |=

Först verkar den här koden fungera bra:

a=1; ((a? b=1 : 2 )) #seems to work 

Men när jag använder tilldelningsoperatörer efter :, fick jag ”försök att tilldela till icke-variabelt” fel:

a=1; ((a? b=1 : c=1)) #attempted assignment to non-variable error 

Varför kan vi bara använda tilldelningsoperatorer före kolon?

Kommentarer

  • Det kan vara kul att utföra variabla tilldelningar med den villkorliga operatören men det ' d gör din kod mycket oläslig. Jag ' Jag föredrar ((a)) && b=1 || c=1
  • @devnull Jag tror att koden ' s läsbarhet beror mest på vem som läser den. Det kan ändå vara sant vad du säger, men jag ' har testat ternary operatörer i dash, zsh, sh och bash och de beter sig alla på samma sätt trots att de inte har specificerats av POSIX. Ditt exempel fungerar bara i bash och zsh så vitt jag vet. Detta är dock POSIX-vänligt: ( : ${a?} ) && b=1 || c=1. Jag tycker också att det är mycket lättare att läsa än ternary eller ditt eget exempel.

Svar

Bash analyserar ditt senaste kommando som

a=1; (( (a? b=1 : c)=1 )) 

vilket bör tydliggöra varför det inte fungerar. Istället måste du använda

a=1; (( a? b=1 : (c=1) )) 

Svar

Detta kallas en ternary assignment uttryck. Här ”är lite från ett annat av mina svar:

% 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 

Du ser, som du säger, detta är en villkorad tilldelningsoperation. Det beror på förhållandena. Syntaxen fungerar så här:

$((var = $condition <compare_operator> $condition \ ?if $true_assign :or $false_assign )) 

Jag tror inte att du använder det här korrekt.

Från wikipedia :

?: används enligt följande:

condition ? value_if_true : value_if_false

Villkoret utvärderas som sant eller falskt som ett booleskt uttryck. På grundval av utvärderingen av det booleska villkoret returnerar hela uttrycket value_if_true om villkoret är sant, men value_if_false annars. Vanligtvis måste de två deluttrycken value_if_true och value_if_false ha samma typ, som bestämmer typen av hela uttrycket. Vikten av denna typkontroll ligger i operatörens vanligaste användning – i villkorade tilldelningsuttalanden. I denna användning visas det som ett uttryck på höger sida av ett uppdragsuttalande, enligt följande:

variable = condition ? value_if_true : value_if_false

?: -operatören liknar hur villkorliga uttryck (if-then-else -konstruktioner) fungerar i funktionella programmeringsspråk, som Scheme, ML och Haskell, eftersom if-then-else bildar en uttryck istället för ett uttalande på dessa språk.

Jag tror att ditt specifika problem är relaterat till detta:

Som i if-else-konstruktionen utvärderas endast ett av uttrycken ”x” och ”y”.

Om du läser igenom länken ovan på ternary uttryck du kommer att se den utvärderingen n är kortsluten så din uppgift på falska sidofelen eftersom 1 = true.

I alla fall spelar det ingen roll för mycket eftersom jag inte tror att det här gör vad du tror det gör.

Svar

Ternära operatörer returnerar ett värde baserat på ett test. De används inte för förgrening.

Här är ett sätt att få en pseudo-ternär operatör för bash (notera back-fästingarna):

$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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *