bash set -o errexit problema ou a maneira de incrementar variável?

2

Eu tenho um shell script incrementando uma variável como no exemplo abaixo com set -e:

$ var=0; echo $?
0
$ ((var++)); echo $?
1
$ ((var++)); echo $?
0
$ ((var++)); echo $?
0
$ echo $var; echo $?
3
0
$ bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later  <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.    
$

O script sai inesperadamente. A coisa é que o mesmo script não sai da mesma maneira quando executado localmente em um MacBook. O shell bash no MacBook se comporta exatamente da mesma maneira ao executar o exemplo acima.

Alguém tem alguma idéia do que está acontecendo aqui?

    
por Marcel 14.04.2016 / 16:50

2 respostas

2

Um comando aritmético é bem sucedido se o valor da expressão aritmética for diferente de zero. Se o valor da expressão for 0, o comando falhará com o status 1. Isso permite que os comandos aritméticos sejam usados nos testes, pois os operadores booleanos nas expressões aritméticas do shell retornam 0 para true e 1 para false (como em C). Por exemplo

if ((x==3)); then …

funciona porque ((x==3)) retorna 0 quando $x é igual a 3 e 1 caso contrário.

O operador de incremento de postfix retorna o valor antigo da variável. Portanto, ((var++)) retornará um status de erro se var foi anteriormente zero.

set -e diz ao shell para sair no primeiro comando que falha. Não há surpresas lá.

Para evitar erros indesejados resultantes de expressões aritméticas que podem legitimamente ter o valor 0, não use comandos aritméticos, use uma atribuição comum com uma expressão aritmética.

var=$((var+1))
    
por 15.04.2016 / 01:09
0

Você sempre pode usar comandos aritméticos como ((var++)) . Se o valor de var antes da atribuição era 0, para forçar um código de status bem-sucedido, você pode escrever: ((var++)) || true

Ou você pode escrever isso para pular a lógica errexit: ! ((var++))

    
por 17.01.2018 / 10:50