Em um script, tenho uma matriz associativa como:
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
Existe um único comando para transformar isso em uma lista de parâmetros no formulário
--key1=value1 --key2=value2
sem ter que reescrever manualmente
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
o caso de uso que eu tinha em mente era passar a matriz para um script como uma lista de parâmetros, como
my_script.sh $(to_param_list $VARS)
Para expandir o comentário que fiz na resposta do @Kusalananda, meu caso de uso exato é o seguinte: Eu tenho um script que é usado para criar um instalador de extração automática usando o makeelf, e esse script recebe alguns parâmetros que devem ser separados entre:
- parâmetros para o próprio script
- parâmetros para o instalador dentro do instalador de extração automática
Os scripts criam o instalador da seguinte maneira:
to_param_list installer_param_list installer_param_array
./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "${installer_param_list[@]}"
No entanto, testei o parâmetro passando com um script de instalação muito simples dentro do pacote:
while ! -z "$1" ; do
echo "$1"
shift
done
e passando uma matriz como:
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
resulta nesta saída:
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
bash
parameter
associative-array
Matteo Tassinari
fonte
fonte
my_script.sh "$(declare -p thearray)$"
. Emmyscript.sh
você lê comsource /dev/stdin <<<"$1"
Então você temthearray
em seu script. Você pode ter outros argumentos ao lado da matriz. Você pode passar muitas variáveis:my_script.sh "$(declare -p var1 var2 ...)"
neste único argumento.Respostas:
Com uma função auxiliar:
O comando final no script acima seria expandido para o equivalente a ter escrito
A
to_param_list
função pega o nome de uma variável de matriz e o nome de uma variável de matriz associativa e os utiliza para criar duas variáveis de "referência de nome" na função (os namerefs foram introduzidos nabash
liberação 4.3). Eles são usados para preencher a variável de matriz fornecida com as chaves e os valores no formato apropriado da matriz associativa.O loop na função repete
"${!inhash[@]}"
, que é a lista de chaves citadas individualmente em sua matriz associativa.Quando a chamada de função retornar, o script usaria a matriz para chamar seu outro script ou comando.
Executando o acima com
o script sairia
Isso mostra que as opções são geradas sem que a divisão de palavras ou o globbing do nome do arquivo entrem em vigor. Também mostra que a ordem das chaves pode não ser preservada, pois o acesso às chaves a partir de uma matriz associativa o fará em uma ordem bastante aleatória.
Você não pode realmente usar uma substituição de comando com segurança aqui, pois o resultado seria uma única string. Se não estiver entre aspas, essa sequência será dividida em caracteres de espaço em branco (por padrão), que dividiriam adicionalmente as chaves e os valores de sua matriz associativa. O shell também executaria um globbing de nome de arquivo nas palavras resultantes. Citar duas vezes a substituição de comando não ajudaria, pois isso resultaria em chamar seu
my_script.sh
com um único argumento.Em relação ao seu problema com
makeself
:O
makeself
script faz isso com os argumentos do script do instalador:Isso salva os argumentos como uma sequência
$SCRIPTARGS
(concatenada, separada por espaços). Posteriormente, ele é inserido no arquivo de extração automática como está. Para que as opções sejam analisadas corretamente quando são reavaliadas (que são ao executar o instalador), você precisará fornecer um conjunto extra de cotações nos valores dos parâmetros para que sejam delimitados corretamente.Observe que isso não é um bug no meu código. É apenas um efeito colateral da
makeself
produção de código shell com base nos valores fornecidos pelo usuário.Idealmente, o
makeself
script deve ter escrito cada um dos argumentos fornecidos com um conjunto extra de aspas, mas não é presumível, porque é difícil saber qual efeito isso pode ter. Em vez disso, deixa ao usuário fornecer essas cotações extras.Reexecutando meu teste de cima, mas agora com
produz
Você pode ver que essas cadeias, quando reavaliadas pelo shell, não seriam divididas em espaços.
Obviamente, você pode usar sua matriz associativa inicial e adicionar as aspas na
to_param_list
função alterandopara dentro
Uma dessas alterações no seu código incluiria aspas simples nos valores das opções, portanto, uma reavaliação dos valores seria necessária .
fonte
"--$param=${inhash[$param]}"
ou dentro"${list[@]}"
, ou o script que recebe as opções faz algo errado ao analisá-las.