Operador e designação condicional do Bash

6

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

Manual de referência do bash explica os operadores aritméticos da seguinte forma.

  • 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 depois de : , recebi o erro 'tentativa de atribuição a 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 do cólon?

    
por MS.Kim 27.04.2014 / 05:19

3 respostas

4

Bash analisa seu último comando como

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

que deve deixar claro porque não funciona. Em vez disso você tem que usar

a=1; (( a? b=1 : (c=1) ))
    
por 27.04.2014 / 06:18
2

Isso é chamado de expressão ternary assignment . Aqui está um pouco 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

Você vê, como você diz, essa é 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 ))

Eu não acredito que você esteja usando isso corretamente.

De wikipedia :

?: is used as follows:

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, toda a expressão retorna value_if_true se a condição for verdadeira, mas value_if_false caso contrário. Geralmente, 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 tipos está no uso mais comum do operador - em instruções de atribuição condicional. Nesse uso, ele aparece como uma expressão no lado direito de uma instrução de atribuição, da seguinte maneira:

     

variable = condition ? value_if_true : value_if_false

     

O operador ?: é semelhante ao modo como as expressões condicionais ( if-then-else constructs) funcionam em linguagens de programação funcionais, como Scheme, ML e Haskell, pois if-then-else forma uma expressão em vez de uma instrução naquelas idiomas.

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

As in the if-else construct only one of the expressions 'x' and 'y' are evaluated.

Se você ler o link acima nas expressões ternary , verá que a avaliação está em curto-circuito, portanto, sua atribuição nos erros do lado falso porque 1 = true .

De qualquer forma, não importa muito, porque não acho que isso aconteça.

    
por 27.04.2014 / 12:24
1

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

Aqui está uma maneira de obter um operador pseudo-ternário para o bash (observe as reticências):

$result='[ < condition > ] && echo "true-result" || echo "false-result" '

$ a= %código% %código% %código% %código% %código% %código% %código% 1

    
por 14.10.2016 / 18:59