Como o bash avaliará o código a seguir?

7

Esta questão tem duas partes:

(a) Entendendo o que o código está sendo executado

(b) Entendendo a diferença entre status de saída e status de retorno no contexto de bash .

Aqui está o código que eu estou tentando entender:

if var=-2 && (( var+=2 ))
then
    echo "True"
else
    echo "False"
fi

Rodar isto produz False . Não consigo entender por que isso está acontecendo.

Se eu entendi corretamente, aqui está o que talvez esteja acontecendo com a condição if :

(a) var=-2 cria o status de saída 0, porque a atribuição é um sucesso

(b) (( var+=2 )) adiciona 2 ao valor de var e a expressão avalia zero. Então, o status de saída é 1 para este termo

(c) 0 & & 1 cria um status de 0 que é usado por if construct

A construção if deve simplesmente verificar o status de saída e, quando é zero, leva o caminho e . Na etapa (c) acima, é zero, mas o script ainda usa o caminho else . Esta maneira correta de entender isso?

Além disso, continuo vendo vários bash textos usar status de saída e retornar status alternadamente.

Eu duvido que a atribuição var=-2 tenha algum tipo de status de saída porque não é um programa. Mas qualquer esclarecimento sobre a diferença entre dois será ótimo.

    
por sshekhar1980 22.05.2017 / 12:29

3 respostas

10

Isso é:

if
  first list of commands
then
  second list of commands
else
  third list of commands
fi

Isso é para executar a segunda lista de comandos se a primeira lista de comandos retornar com um status de saída verdadeiro / sucesso (zero), ou seja, se o último comando de execução lá retorna com um status de saída zero.

Em:

var=-2 && ((var += 2))

É cmd1 && cmd2 , em que cmd2 só é executado se cmd1 for bem-sucedido.

var=-2

Em geral, será bem-sucedido, desde que $var não tenha sido somente leitura, portanto, o comando ((var += 2)) será executado:

((arithmetic expression))

Retorna sucesso / verdadeiro desde que a expressão seja corretamente avaliada (sem erro de sintaxe) e o resultado da expressão seja diferente de zero.

  • ((123)) , ((1 + 1)) , ((1 == 1)) return true
  • ((0)) , ((-2 + 2)) , ((2 == -2)) return false.
  • ((4294967296 * 4294967296)) retorna falso na maioria dos shells devido a quebra de números inteiros de 64 bits

var += 2 como uma expressão aritmética, executa a atribuição e resolve o valor que está sendo atribuído, aqui 0, portanto, o status de saída falso .

Você pode ver o valor com base no status de saída, usando a sintaxe de expansão aritmética $((...)) :

$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0

Ou atribuindo-o a uma variável:

$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0

$? contém o status de saída do comando anterior. No que diz respeito a if / then / else / fi , 0 significa verdadeiro, qualquer outra coisa significa falso.

A confusão vem do fato de que, para expressões aritméticas, ocorre o contrário: 0 significa falso e qualquer outra coisa significa verdadeiro (por exemplo, 2 == 2 é 1 , enquanto 2 < 1 é 0 ).

Para evitar se preocupar com a diferença, esqueça de $? e seus possíveis valores. Pense apenas em termos de true / falso , sucesso / falha .

 grep -q foo file

Retorna verdadeiro se foo for encontrado em file .

 [ "$a" = "$b" ]

Retorna verdadeiro se $a contiver a mesma coisa que $b .

 ((6 * 3 - 12))
 ((4 == 1))

Retorna verdadeiro se o resultado da expressão aritmética for um número diferente de zero.

Não importa se os true / false são expressos em termos de 0 ou 1 do status de saída desses comandos grep / [ ou ((...)) construct.

    
por 22.05.2017 / 12:42
3

(c) 0 && 1 creates an exist status of 0 which is then used by if construct

Existe o erro. 0 & & 1 resultados em 1 . Isso não é C ou Java, lembre-se. Na casca 0 & & 1 é o que você obteria de true && false .

$ true; echo $?
0
$ false; echo $?
1
$ true && false; echo $?
1

Also, I keep seeing various bash texts use exit status and return status interchangeably.

Eles são intercambiáveis. O que você deseja ter em mente é que 0 indica sucesso e não 0 indica falha. É o oposto da maioria das linguagens de programação, em que 0 é falso e 1 é verdadeiro.

    
por 22.05.2017 / 17:17
0

Tudo está funcionando como esperado.

if var=-2 && (( var+=2 ))
then
    echo "True"
else
    echo "False"
fi

Explicação do código: -

if var=-2 && (( var+=2 ))

var=-2 => true O valor é diferente de zero, então avaliado como verdadeiro

var+=2 => false O valor é zero, então avaliado como falso

isso é como

if true && false

De acordo com o cálculo lógico, true & & false = > falso

Nesse caso, aqui está nosso código final

if (false)
then
    echo "True"
else
    echo "False"
fi
    
por 22.05.2017 / 13:10

Tags