Operador condicional e atribuição do ' Bash

Podemos usar o operador condicional do bash com operadores de atribuição após dois pontos?

O manual de referência do Bash explica os operadores aritméticos da seguinte maneira.

  • operador condicional expr ? expr : expr
  • atribuição = *= /= %= += -= <<= >>= &= ^= |=

Primeiro, este código parece funcionar bem:

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

Mas quando eu uso operadores de atribuição após :, recebo o erro “tentativa de atribuição para não variável”:

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

Por que podemos usar apenas operadores de atribuição antes de dois pontos?

Comentários

  • Pode ser divertido realizar atribuições de variáveis usando o operador condicional, mas ' d torna seu código altamente ilegível. Eu ' d prefiro ((a)) && b=1 || c=1
  • @devnull Acho que o código ' s a legibilidade depende muito de quem o lê. Ainda assim, pode ser verdade o que você diz, mas eu ' testei ternary operadores em dash, zsh, sh e bash e todos se comportam da mesma forma, apesar de não serem especificados por POSIX. Seu exemplo só funciona em bash e zsh até onde eu sei. No entanto, isso é compatível com POSIX: ( : ${a?} ) && b=1 || c=1. Também acho muito mais fácil de ler do que ternary ou seu próprio exemplo.

Resposta

O Bash analisa seu último comando como

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

o que deve deixar claro por que ele não funciona. Em vez disso, você deve usar

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

Resposta

Isso é chamado de ternary assignment expressão. Aqui está um trecho de outra resposta minha:

% 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 

Veja, como você disse, esta é uma operação de atribuição condicional . Depende das condições. A sintaxe funciona assim:

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

Não acredito que você esteja usando isso corretamente.

De wikipedia :

?: é usado da seguinte forma:

condition ? value_if_true : value_if_false

A condição é avaliada como verdadeira ou falsa como uma expressão booleana. Com base na avaliação da condição booleana, a expressão inteira retorna valor_se_verdadeira se a condição for verdadeira, mas valor_se_falso caso contrário. Normalmente, as duas subexpressões value_if_true e value_if_false devem ter o mesmo tipo, o que determina o tipo de toda a expressão. A importância dessa verificação de tipo reside no uso mais comum do operador – em instruções de atribuição condicional. Nesse uso, ela aparece como uma expressão no lado direito de uma instrução de atribuição, como segue:

variable = condition ? value_if_true : value_if_false

O ?: operador é semelhante à maneira como as expressões condicionais (if-then-else construções) funcionam em linguagens de programação funcionais, como Scheme, ML e Haskell, uma vez que if-then-else forma um expressão em vez de uma declaração nessas línguas.

Acho que seu problema específico está relacionado a este:

Como na construção if-else, apenas uma das expressões “x” e “y” são avaliadas.

Se você ler o link acima nas expressões ternary você verá essa avaliação n está em curto-circuito, portanto, sua atribuição nos erros secundários false porque 1 = true.

Em qualquer caso, não importa demais porque não acho que isso faça o que você pensa que faz.

Resposta

Operadores ternários retornam um valor com base em um teste. Eles não são usados para ramificação.

Esta é uma maneira de obter um operador pseudo-ternário para bash (observe os back-ticks):

$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

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *