Com uma função auxiliar:
#!/bin/bash
to_param_list () {
declare -n outlist=$1
declare -n inhash=$2
for param in "${!inhash[@]}"; do
outlist+=( "--$param=${inhash[$param]}" )
done
}
declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )
to_param_list list my_vars
my_script.sh "${list[@]}"
O comando final no script acima seria expandido para o equivalente a ter escrito
my_script.sh "--key2=value" "--key1=value1"
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 na bash
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
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
o script sairia
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
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 commakeself
:
O makeself
script faz isso com os argumentos do script do instalador:
SCRIPTARGS="$*"
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.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
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
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
produz
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
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 alterando
outlist+=( "--$param=${inhash[$param]}" )
para dentro
outlist+=( "--$param='${inhash[$param]}'" )
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 .
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.