Bash ' s operador condicional y asignación

¿Podemos usar el operador condicional de bash con operadores de asignación después de dos puntos?

Bash Reference Manual explica los operadores aritméticos de la siguiente manera.

  • operador condicional expr ? expr : expr
  • asignación = *= /= %= += -= <<= >>= &= ^= |=

Primero, este código parece funcionar bien:

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

Pero cuando uso operadores de asignación después de :, aparece el error «intento de asignación a no variable»:

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

¿Por qué podemos usar solo operadores de asignación antes de los dos puntos?

Comentarios

  • Puede ser divertido realizar asignaciones de variables con el operador condicional, pero ' haría que su código fuera muy ilegible. Yo ' prefiero ((a)) && b=1 || c=1
  • @devnull Creo que el código ' La legibilidad depende principalmente de quién lo lea. Aún así, puede ser cierto lo que dice, pero ' he probado ternary operadores en dash, zsh, sh y bash y todos se comportan de la misma manera, a pesar de que POSIX no los especifica. Su ejemplo solo funciona en bash y zsh hasta donde yo sé. Sin embargo, esto es compatible con POSIX: ( : ${a?} ) && b=1 || c=1. También lo encuentro mucho más fácil de leer que ternary o su propio ejemplo.

Respuesta

Bash analiza su último comando como

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

lo que debería aclarar por qué no funciona. En su lugar, debe utilizar

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

Respuesta

Esto se llama ternary assignment expresión. Aquí «un poco de otra respuesta mía:

% 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 

Como ves, como dices, esta es una operación de asignación condicional . Depende de las condiciones. La sintaxis funciona así:

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

No creo que esté usando esto correctamente.

De wikipedia :

?: se utiliza de la siguiente manera:

condition ? value_if_true : value_if_false

La condición se evalúa como verdadera o falsa como una expresión booleana. Sobre la base de la evaluación de la condición booleana, la expresión completa devuelve valor_si_verdadero si la condición es verdadera, pero valor_si_falso en caso contrario. Por lo general, las dos subexpresiones value_if_true y value_if_false deben tener el mismo tipo, lo que determina el tipo de toda la expresión. La importancia de esta verificación de tipos radica en el uso más común del operador: en declaraciones de asignación condicional. En este uso, aparece como una expresión en el lado derecho de una declaración de asignación, como sigue:

variable = condition ? value_if_true : value_if_false

El ?: operador es similar a la forma en que las expresiones condicionales (if-then-else construcciones) funcionan en lenguajes de programación funcionales, como Scheme, ML y Haskell, ya que if-then-else forma un expresión en lugar de una declaración en esos idiomas.

Creo que su problema específico está relacionado con esto:

Como en la construcción if-else, solo se evalúa una de las expresiones «x» e «y».

Si lee el enlace anterior sobre ternary expresiones verás esa evaluación n está cortocircuitado por lo que su asignación en el lado falso errores porque 1 = true.

En cualquier caso, no importa demasiado porque no creo que esto haga lo que crees que hace.

Respuesta

Los operadores ternarios devuelven un valor basado en una prueba. No se utilizan para ramificar.

Aquí hay una forma de obtener un operador pseudo-ternario para bash (tenga en cuenta las marcas de retroceso):

$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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *