Compreender dois exemplos usando expansão indireta para expansão de variável em expressões aritméticas

2

Stéphane Chazelas deu dois exemplos em O valor de uma variável é avaliado como uma expressão aritmética quando é referenciada ou atribuída

$ a=1+1; echo "$((a * 3)) $(($a * 3))"
6 4

$ a=a=b++ b=1 bash -c 'echo "$((++a)) $b"'
2 2

Eu entendo que há expansão indireta para expansão de variáveis em expressões aritméticas. Mas eu não consigo descobrir

  • como a e $a no primeiro exemplo resultam em tal diferença? Minha confusão vem do que em expressões aritméticas, a expansão de parâmetros de uma variável não precisa de ${} , apenas escreva a variável diretamente.

  • como é avaliada a expressão aritmética no segundo exemplo?

Obrigado.

    
por Tim 28.07.2017 / 00:13

1 resposta

4

A expansão de parâmetros não é o mesmo que avaliação aritmética .

Em uma expressão aritmética, uma cadeia de texto como a é interpretada como um nome de variável, e o valor dessa variável é processado como uma expressão aritmética e o resultado usado na expressão aritmética de contenção. Assim

$((a * 3))

faz com que o valor da variável a , 1+1 , seja avaliado como uma expressão aritmética, produzindo 2 , e toda a expressão se torna $((2 * 3)) , ie 6 .

No mesmo contexto, $a é substituído pelo valor de a as-is, em uma fase anterior ( isso é a expansão de parâmetro); então

$(($a * 3))

torna-se $((1+1 * 3)) , que é 4 seguindo as regras de precedência usuais.

No segundo exemplo, $((++a)) é processado antes de $b (o processamento ocorre da esquerda para a direita). A expressão aritmética faz com que a seja avaliado como uma expressão aritmética, como acima; o valor de a é a=b++ , que, quando avaliado, atribui o valor de b (avaliado como uma expressão aritmética) a a e, em seguida, incrementa b . Assim, após avaliar a , b é 2 e a é 1 . Avaliando $((++a)) incrementos a e retorna seu valor, que agora é 2 . $b acabou de ser substituído pelo valor de b , 2 também. Depois que o argumento citado para echo é processado, o echo é executado com 2 2 como seu único argumento, produzindo a saída que você viu.

    
por 28.07.2017 / 00:37

Tags