Looping através de uma matriz com para resultados diferentes

0

Estou tendo um problema com uma matriz no bash.

Dado este array:

 krn=(linux-image-4.15.0-30-generic linux-image-4.15.0-32-generic linux-image-4.15.0-33-generic)

Se eu usar o loop a seguir para iterá-lo, obtenho resultados diferentes sem alterar nada:

1ª vez:

for krn in ${krn[@]};do echo $krn;done
linux-image-4.15.0-30-generic
linux-image-4.15.0-32-generic
linux-image-4.15.0-33-generic

2ª vez:

for krn in ${krn[@]};do echo $krn;done
linux-image-4.15.0-33-generic
linux-image-4.15.0-32-generic
linux-image-4.15.0-33-generic

O que estou fazendo de errado?

Se eu usar um estilo C para o comprimento do array, ele não terá esse comportamento estranho.

for ((i=0; i<${#krn[@]}; i++)); do echo ${krn[i]};done
    
por Costin Balan 16.11.2018 / 10:02

1 resposta

2

Seu loop usa krn como a variável de loop. Esse também é o nome da matriz que você passa por cima. O shell não mantém espaços de nomes separados para variáveis de matriz e variáveis não matriciais.

Para cada iteração, krn será definido para o valor atual da matriz. Isso tem o efeito de modificar o primeiro elemento da matriz em cada iteração. O loop modifica a matriz para que o primeiro elemento seja uma cópia do último elemento após o final do loop.

Para corrigir isso, escolha outro nome para a variável de loop ou para a matriz.

Além disso, você deve usar "${krn[@]}" (a expansão, aspas duplas) no cabeçote de loop, pois usar ${krn[@]} não-citado dividiria cada elemento em espaços em branco (ou o que for em $IFS ) e invocar o globeamento de nomes no resultado palavras. O mesmo vale para echo "${krn[i]}" no último loop.

Supondo que haja pelo menos um elemento na matriz, o loop inteiro poderia alternativamente ser substituído por

printf '%s\n' "${krn[@]}"
    
por 16.11.2018 / 10:14