Como o bash avaliará o código a seguir

Como o bash avaliará o código a seguir

Esta questão tem duas partes:

(a) Compreender o que o código cortado está fazendo

(b) Compreender a diferença entrestatus de saídaestatus de retornono contexto de bash.

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

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

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

Se bem entendi, aqui está o que talvez esteja acontecendo com a ifcondição:

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

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

(c) 0 && 1 cria um status de existência de 0 que é então usado pela ifconstrução

A ifconstrução deve simplesmente verificar o status de saída e quando for zero, leva oentãocaminho. Na etapa (c) acima é zero, mas o script ainda leva ooutrocaminho. Essa é a maneira correta de entender isso?

Além disso, continuo vendo vários bashtextos usaremstatus de saídaestatus de retornointercambiavelmente.

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

Responder1

Isso é:

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

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

Em:

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

É cmd1 && cmd2onde cmd2só é executado se cmd1tiver sucesso.

var=-2

Normalmente terá sucesso desde que $varnão tenha sido tornado somente leitura, então o ((var += 2))comando será executado:

((arithmetic expression))

Devoluçõessucesso/verdadeirodesde que a expressão seja avaliada corretamente (sem erro de sintaxe) e o resultado da expressão seja diferente de zero.

  • ((123)), ((1 + 1)), ((1 == 1))retornar verdadeiro
  • ((0)), ((-2 + 2)), ((2 == -2))retorna falso.
  • ((4294967296 * 4294967296))retorna falso na maioria dos shells devido ao empacotamento inteiro de 64 bits

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

Você pode ver o valor no qual se baseia o 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 outro valor significa falso.

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

Para não se preocupar com a diferença, esqueça $?e seus possíveis valores. Basta pensar em termos de booleanoverdadeiro/falso,sucesso/falha.

 grep -q foo file

Retorna verdadeiro se foofor encontrado em file.

 [ "$a" = "$b" ]

Retorna verdadeiro se $acontiver o mesmo que $b.

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

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

Não importa se aquelesverdadeiro/falsosão expressos em termos de 0 ou 1 do status de saída desses grep/ [comandos ou ((...))construção.

Responder2

(c) 0 && 1 cria um status de existência de 0 que é então usado pela ifconstrução

Aí está o erro. 0 && 1 resulta em 1. Isso não é C ou Java, lembre-se. No shell 0 && 1 é o que você obteria de true && false.

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

Além disso, continuo vendo vários textos bash usarem o status de saída e o status de retorno de forma intercambiável.

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

Responder3

Tudo está funcionando conforme o 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

isto é como

if true && false

De acordo com a computação lógicaverdadeiro && falso => ​​falso

Nesse caso aqui está nosso código final

if (false)
then
    echo "True"
else
    echo "False"
fi

informação relacionada