Como funciona a aritmética de bash?

1
 read num1
 2
 read num2
 5
 echo "$((num1+num2))"
 7
 echo "$(($num1+$num2))"
 7

Eu consultei este .

Eu não entendo como as duas expressões acima produzem o mesmo resultado? Por favor explique.

    echo "$[num1+num2]" 

Não funciona como sugerido nessa pergunta. Estou fazendo algo errado?

    echo 'expr "$num1" + "$num2"' 

também não funciona. Por favor, forneça algumas sugestões.

    
por Gops AB 22.12.2014 / 09:09

2 respostas

1

No shell POSIX, Expansão aritmética tem forma:

$((expression))

Se a expressão contiver variáveis, e essas variáveis contiverem um valor de inteiro válido, o sinal de mais ou de menos é bom - então "$((var))" e "$(($var))" retornarão o mesmo resultado (Nota: using dados não-analizados na avaliação aritmética da shell leva à implicação de segurança).

O formulário $ [expression] não é definido por POSIX, foi preterido e será removido em próxima versão de bash .

O utilitário expr pode ser usado para fazer cálculos aritméticos. No seu caso, você usou a sintaxe errada para substituição de comando , é um backstack, não um citação simples:

echo 'expr "$num1" + "$num2"'

Mas você deve usar "$()" em vez disso.

    
por 22.12.2014 / 10:31
3

Para avaliar uma expressão aritmética, o shell primeiro expande a variável e as substituições de comando dentro dela. Por exemplo, em echo "$(($num1+$num2))" , a primeira coisa que acontece é que $num1 e $num2 são substituídos pelos valores das variáveis. A expressão se torna 2+5 . Isso é analisado como uma expressão aritmética e avaliado para o número 7. O resultado da análise e expansão de "$(($num1+$num2))" é, portanto, 7 .

As expressões aritméticas podem conter nomes de variáveis. Estes são avaliados para o valor da variável. Assim, $((num1+num2)) é a expressão aritmética num1+num2 (enquanto $(($num1+$num2)) é a expressão aritmética 2+5 ). Neste caso, o resultado é o mesmo.

As duas expressões são diferentes quando o valor de num1 ou num2 não é apenas uma sequência de dígitos. Por exemplo, considere o seguinte snippet:

a="1+2"
echo "$(($a * 4))"
echo "$((a * 4))"

Na segunda linha, a expressão aritmética a ser avaliada é 1+2 * 4 . Isso é analisado como 1 + (2 × 4), pois a multiplicação tem uma precedência maior que a adição. O fato de que o sinal de mais veio da expansão de uma variável é esquecido no momento em que a avaliação aritmética ocorre. O resultado é o número 9, então a primeira chamada para echo imprime 9 .

O comportamento da terceira linha depende do shell. Algumas conchas (por exemplo, traço) reclamam que a não contém um valor numérico válido. Outras shells (por exemplo, ksh, bash, zsh) tratam o valor de a como uma subexpressão que é avaliada para obter o valor a ser usado na expressão principal. Ou seja, nesses outros shells, o valor de a é avaliado como 3 e a expressão aritmética calcula 3 × 4, então o resultado é 12.

Por fim, $[…] é uma variante descontinuada e não padrão de $((…)) . O utilitário expr é uma maneira antiga de fazer cálculos aritméticos em scripts de shell, desde o momento em que os shells não tinham uma sintaxe aritmética embutida. expr "$num1" + "$num2" imprime 7, assim como o echo 'expr "$num1" + "$num2"' redundante (você digitou incorretamente uma das aspas).

    
por 23.12.2014 / 02:13