Mit einer Hilfsfunktion:
#!/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[@]}"
Der letzte Befehl im obigen Skript würde sich auf das Äquivalent des Schreibens erweitern
my_script.sh "--key2=value" "--key1=value1"
Die to_param_list
Funktion verwendet den Namen einer Arrayvariablen und den Namen einer assoziativen Arrayvariablen und verwendet diese, um zwei "Namensreferenz" -Variablen in der Funktion zu erstellen (namerefs wurden in bash
Version 4.3 eingeführt). Diese werden dann verwendet, um die angegebene Array-Variable mit den Schlüsseln und Werten im entsprechenden Format aus dem assoziativen Array zu füllen.
Die Schleife in der Funktion durchläuft "${!inhash[@]}"
die Liste der einzeln in Anführungszeichen gesetzten Schlüssel in Ihrem assoziativen Array.
Sobald der Funktionsaufruf zurückkehrt, verwendet das Skript das Array, um Ihr anderes Skript oder Ihren anderen Befehl aufzurufen.
Führen Sie die oben genannten mit
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
Das Skript würde ausgegeben
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
Dies zeigt, dass die Optionen generiert werden, ohne dass Wortteilung oder Dateinamen-Globbing wirksam werden. Es zeigt auch, dass die Reihenfolge der Schlüssel möglicherweise nicht beibehalten wird, da der Zugriff auf die Schlüssel aus einem assoziativen Array in einer ziemlich zufälligen Reihenfolge erfolgt.
Sie können eine Befehlssubstitution hier nicht wirklich sicher verwenden, da das Ergebnis eine einzelne Zeichenfolge wäre. Wenn diese Zeichenfolge nicht in Anführungszeichen gesetzt ist, wird sie (standardmäßig) in Leerzeichen aufgeteilt, wodurch zusätzlich sowohl die Schlüssel als auch die Werte Ihres assoziativen Arrays aufgeteilt werden. Die Shell würde auch Dateinamen-Globbing für die resultierenden Wörter ausführen. Das doppelte Zitieren der Befehlsersetzung würde nicht helfen, da dies dazu führen würde, dass Sie my_script.sh
mit einem einzigen Argument aufgerufen werden.
In Bezug auf Ihr Problem mitmakeself
:
Das makeself
Skript führt dies mit den Argumenten für Ihr Installationsskript aus:
SCRIPTARGS="$*"
Dadurch werden die Argumente als Zeichenfolge $SCRIPTARGS
gespeichert (verkettet, durch Leerzeichen getrennt). Dies wird später unverändert in das selbstextrahierende Archiv eingefügt. Für die Optionen richtig analysiert werden , wenn sie neu bewertet (was sie sind , wenn das Installationsprogramm ausgeführt wird ), erhalten Sie einen bereitstellen müssen , um zusätzlichen Satz von Anführungszeichen in den Werten der Parameter für sie richtig abgegrenzt werden.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
Beachten Sie, dass dies kein Fehler in meinem Code ist. Es ist nur ein Nebeneffekt beim makeself
Erstellen von Shell-Code basierend auf vom Benutzer angegebenen Werten.
Im Idealfall sollte das makeself
Skript jedes der bereitgestellten Argumente mit zusätzlichen Anführungszeichen versehen haben, dies ist jedoch nicht der Fall, da es schwierig ist zu wissen, welche Auswirkungen dies haben kann. Stattdessen überlässt es dem Benutzer, diese zusätzlichen Anführungszeichen bereitzustellen.
Wiederholen Sie meinen Test von oben, aber jetzt mit
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
produziert
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
Sie können sehen, dass diese Zeichenfolgen bei einer Neubewertung durch die Shell nicht auf Leerzeichen aufgeteilt werden.
Natürlich können Sie Ihr anfängliches assoziatives Array verwenden und stattdessen die Anführungszeichen in die to_param_list
Funktion einfügen, indem Sie sie ändern
outlist+=( "--$param=${inhash[$param]}" )
in
outlist+=( "--$param='${inhash[$param]}'" )
Jede dieser Änderungen an Ihrem Code würde die einfachen Anführungszeichen in den Werten der Optionen enthalten, sodass eine Neubewertung der Werte erforderlich würde .
my_script.sh "$(declare -p thearray)$"
. Inmyscript.sh
lesen Sie es mitsource /dev/stdin <<<"$1"
Dann haben Siethearray
in Ihrem Skript. Sie können neben dem Array auch andere Argumente verwenden. Sie können viele Variablen übergeben:my_script.sh "$(declare -p var1 var2 ...)"
in diesem einzelnen Argument.