Variáveis do shell em um loop for

6

Eu tenho dificuldade em superar essa man bash passagem.

                          If the control variable in a for loop has the
nameref attribute, the list of words can be a list of shell  variables,
and  a name reference will be established for each word in the list, in
turn, when the loop is executed.  Array variables cannot be  given  the
-n attribute.  However, nameref variables can reference array variables
and subscripted array variables.

Você poderia dar um exemplo dessa variável nameref em um loop com alguma explicação?

    
por Tomasz 14.03.2017 / 00:34

1 resposta

5

Uma variável nameref é para uma variável “normal” o que um link simbólico é para um arquivo regular.

$ typeset -n ref=actual; ref=foo; echo "$actual"
foo

Um loop for executa o corpo com a variável de loop (a "variável de controle") ligada a cada palavra da lista.

$ for x in one two three; do echo "$x"; done
one
two
three

Isso equivale a escrever tarefas sucessivas:

x=one; echo "$x"
x=two; echo "$x"
x=three; echo "$x"

Se a variável de loop for um nameref, o corpo será executado com o nameref tendo por alvo cada elemento da lista de palavras. Isso não equivale a uma série de atribuições como acima: uma atribuição ref=value onde ref é um nameref afetaria a variável para a qual ref está apontando, mas o loop for muda onde a nomeref aponta em vez de seguir a referência para mudar a variável para a qual ela aponta.

$ original=0; one=1; two=2; three=3
$ typeset -n ref=original
$ echo $ref
0
$ for ref in one two three; do echo "$ref"; done
1
2
3
$ echo original
0

A indirecção pode ser observada através de atribuições também, se você atribuir à variável de loop (o que é incomum, mas permitido).

$ one=1; two=2; three=3
$ typeset -n ref
$ for ref in one two three; do echo ref=$((ref+10)); done
$ echo "$one $two $three"
11 12 13

A última frase explica que o alvo de um nameref pode ser um array. O nameref em si não é um array, ainda é uma variável escalar, mas quando é usado em uma atribuição ou em um dereference, ele age como o mesmo tipo da variável para a qual ele aponta.

$ a=(0 1 2)
$ typeset -n ref=a
$ ref[1]=changed
$ echo "${a[@]}"
0 changed 2
    
por 14.03.2017 / 02:10