O problema básico aqui é que os desenvolvedores do bash que projetaram / implementaram matrizes realmente estragaram tudo. Eles decidiram que ${array}
era apenas uma mão curta ${array[0]}
, o que foi um grande erro. Especialmente quando você considera que ${array[0]}
não tem significado e avalia a sequência vazia se o tipo de matriz é associativo.
A atribuição de uma matriz assume a forma em array=(value1 ... valueN)
que value tem a sintaxe [subscript]=string
, atribuindo um valor diretamente a um índice específico na matriz. Isso faz com que haja dois tipos de matrizes, indexadas numericamente e indexadas por hash (chamadas matrizes associativas na linguagem do bash). Ele também permite criar matrizes esparsas indexadas numericamente. Sair da [subscript]=
peça é uma abreviação para uma matriz indexada numericamente, começando com o índice ordinal de 0 e incrementando a cada novo valor na instrução de atribuição.
Portanto, ${array}
deve avaliar para toda a matriz, índices e tudo. Deve avaliar o inverso da declaração de atribuição. Qualquer aluno do terceiro ano do ensino médio deve saber disso. Nesse caso, esse código funcionaria exatamente como você pode esperar:
declare -A foo bar
foo=${bar}
Em seguida, passar matrizes por valor para funções e atribuir uma matriz a outra funcionaria como o resto da sintaxe do shell exigir. Mas como eles não fizeram isso corretamente, o operador de atribuição =
não funciona para matrizes, e matrizes não podem ser passadas por valor para funções ou subcascas ou saída em geral ( echo ${array}
) sem código para analisar tudo.
Portanto, se tivesse sido feito corretamente, o exemplo a seguir mostraria como a utilidade de matrizes no bash poderia ser substancialmente melhor:
simple=(first=one second=2 third=3)
echo ${simple}
a saída resultante deve ser:
(first=one second=2 third=3)
Em seguida, as matrizes podem usar o operador de atribuição e serem passadas por valor para funções e até outros scripts de shell. Facilmente armazenado com saída para um arquivo e facilmente carregado de um arquivo para um script.
declare -A foo
read foo <file
Infelizmente, fomos decepcionados por uma equipe superlativa de desenvolvimento do bash.
Como tal, para passar um array para uma função, existe realmente apenas uma opção, e é usar o recurso nameref:
function funky() {
local -n ARR
ARR=$1
echo "indexes: ${!ARR[@]}"
echo "values: ${ARR[@]}"
}
declare -A HASH
HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function
resultará na seguinte saída:
indexes: foo zoom
values: bar fast
Como isso é transmitido por referência, você também pode atribuir à matriz na função. Sim, a matriz que está sendo referenciada deve ter um escopo global, mas isso não deve ser muito importante, considerando que esse é um script de shell. Para passar uma matriz indexada associativa ou esparsa por valor para uma função, é necessário lançar todos os índices e valores na lista de argumentos (não muito útil se for uma matriz grande) como cadeias únicas como esta:
funky "${!array[*]}" "${array[*]}"
e, em seguida, escrevendo um monte de código dentro da função para remontar a matriz.