Comportamento de atribuição de matriz

3

No Bash, os arrays a=( 11 22 ) e b=$(echo "11 22") se comportam de maneira diferente quando impressos.

$ a=( 11 22 )
$ b=$(echo "11 22")
$ echo $b
11 22
$ echo $a
11

Se quisermos imprimir o conteúdo completo de a , temos que recorrer à impressão como ${a[*]} , em oposição a $a .

O que explica essa diferença de comportamento entre uma atribuição de matriz por parênteses e outra por substituição de comando?

    
por Mussé Redi 30.07.2017 / 16:19

2 respostas

4

Para uma matriz (digamos arr ), apenas referindo-se à matriz usando a notação usual de referência de variável $arr é análogo a ${arr[0]} , ou seja, isso se refere ao primeiro elemento da matriz. Isso é o que acontece no seu caso.

Se você quiser se referir a todos os elementos da matriz, quase sempre deseja usar "${arr[@]}" , não "${arr[*]}" . Porque, no último caso, quando citado assim, os elementos seriam mostrados como string única com o primeiro caractere de IFS como separador, por padrão (quando IFS é espaço, guia , newline), o espaço se torna o separador.

No caso em que ${arr[@]} é sem aspas, ele se expande para todos os elementos da matriz com a divisão de palavras e a expansão do nome de caminho ocorrendo ainda mais.

Aqui está um exemplo para você:

$ a=( 11 22 )
$ printf '%s\n' "$a"
11
$ printf '%s\n' "${a[0]}"
11
printf '%s\n' "${a[*]}"
11 22
$ printf '%s\n' "${a[@]}"
11
22

Agora, no caso de b=$(echo "11 22") , você está simplesmente fazendo a substituição de comandos e dentro dessa execução echo "11 12" (em uma subshell), e o resultado está sendo salvo na variável b , que não é um array . Portanto, você recebe 11 12 quando echo -ing $b .

Observe que o lado direito da atribuição de variáveis não passa pela divisão de palavras, portanto, a string 11 12 é salva na variável b , mesmo que haja espaço entre elas.

    
por 30.07.2017 / 16:42
4

Thanks for the below Note from @cas:
$b is NOT an array, it is a string containing "11 22"

O equivalente a

a=( 11 22 )

é

b=($(echo "11 22"))

Como resultado

$ a=( 11 22 )
$ b=($(echo "11 22"))
$ echo $a
11
$ echo ${a[*]}
11 22
$ echo $b
11
$ echo ${b[*]}
11 22
    
por 30.07.2017 / 16:27