Avec une fonction d'assistance:
#!/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[@]}"
La commande finale dans le script ci-dessus s'étendrait à l'équivalent d'avoir écrit
my_script.sh "--key2=value" "--key1=value1"
La to_param_list
fonction prend le nom d'une variable de tableau et le nom d'une variable de tableau associatif et les utilise pour créer deux variables de «référence de nom» dans la fonction (les références de nom ont été introduites dans la bash
version 4.3). Celles-ci sont ensuite utilisées pour remplir la variable de tableau donnée avec les clés et les valeurs au format approprié à partir du tableau associatif.
La boucle de la fonction itère sur "${!inhash[@]}"
, qui est la liste des clés entre guillemets individuels dans votre tableau associatif.
Une fois l'appel de fonction de retour, le script utilise le tableau pour appeler votre autre script ou commande.
Exécution de ce qui précède avec
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
le script afficherait
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
Cela montre que les options sont générées sans que le fractionnement de mot ou le remplacement de nom de fichier n'entrent en vigueur. Cela montre également que l'ordre des clés peut ne pas être conservé, car l'accès aux clés à partir d'un tableau associatif le fera dans un ordre assez aléatoire.
Vous ne pouvez pas vraiment utiliser une substitution de commande en toute sécurité ici car le résultat serait une seule chaîne. Si elle n'est pas entre guillemets, cette chaîne sera ensuite divisée en caractères d'espacement (par défaut), ce qui divisera également les clés et les valeurs de votre tableau associatif. L'interpréteur de commandes exécuterait également un remplacement de nom de fichier sur les mots résultants. La citation double de la substitution de commande n'aiderait pas car cela entraînerait l'appel de votre my_script.sh
avec un seul argument.
Concernant votre problème avecmakeself
:
Le makeself
script fait cela avec les arguments de votre script d'installation:
SCRIPTARGS="$*"
Cela enregistre les arguments sous forme de chaîne $SCRIPTARGS
(concaténés, séparés par des espaces). Celui-ci est ensuite inséré tel quel dans l'archive auto-extractible. Pour que les options soient correctement analysées lorsqu'elles sont réévaluées (ce qu'elles sont lors de l'exécution du programme d'installation), vous devrez fournir un ensemble supplémentaire de guillemets dans les valeurs des paramètres pour qu'elles soient correctement délimitées.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
Notez que ce n'est pas un bug dans mon code. C'est juste un effet secondaire de la makeself
production de code shell basé sur des valeurs fournies par l'utilisateur.
Idéalement, le makeself
script devrait avoir écrit chacun des arguments fournis avec un ensemble supplémentaire de guillemets autour d'eux, mais ce n'est pas le cas, probablement parce qu'il est difficile de savoir quel effet cela peut avoir. Au lieu de cela, il laisse à l'utilisateur le soin de fournir ces devis supplémentaires.
Relancer mon test d'en haut, mais maintenant avec
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
produit
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
Vous pouvez voir que ces chaînes, lorsqu'elles sont réévaluées par le shell, ne sont pas divisées en espaces.
De toute évidence, vous pouvez utiliser votre tableau associatif initial et ajouter à la place les guillemets dans la to_param_list
fonction en changeant
outlist+=( "--$param=${inhash[$param]}" )
dans
outlist+=( "--$param='${inhash[$param]}'" )
L'une ou l'autre de ces modifications de votre code inclurait les guillemets simples dans les valeurs des options, donc une réévaluation des valeurs deviendrait nécessaire .
my_script.sh "$(declare -p thearray)$"
. Enmyscript.sh
vous le lisez avecsource /dev/stdin <<<"$1"
ensuite vous avezthearray
dans votre script. Vous pouvez avoir d'autres arguments à côté du tableau. Vous pouvez passer de nombreuses variables:my_script.sh "$(declare -p var1 var2 ...)"
dans ce seul argument.