In einem Skript habe ich ein assoziatives Array wie:
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
Gibt es einen einzigen Befehl, um dies in eine Parameterliste im Formular umzuwandeln?
--key1=value1 --key2=value2
ohne manuell neu schreiben zu müssen
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
Der Anwendungsfall, an den ich gedacht hatte, bestand darin, das Array als Liste von Parametern an ein Skript zu übergeben
my_script.sh $(to_param_list $VARS)
Um den Kommentar zu der Antwort von @Kusalananda zu erweitern, lautet mein genauer Anwendungsfall wie folgt: Ich habe ein Skript, mit dem ein selbstextrahierendes Installationsprogramm mit makeelf erstellt wird, und dieses Skript empfängt einige Parameter, zwischen denen Folgendes getrennt werden soll:
- Parameter für das Skript selbst
- Parameter für das Installationsprogramm im selbstextrahierenden Installationsprogramm
Die Skripte erstellen dann das Installationsprogramm wie folgt:
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[@]}"
Ich habe die Parameterübergabe jedoch mit einem sehr einfachen Installationsskript im Paket getestet:
while ! -z "$1" ; do
echo "$1"
shift
done
und Übergeben eines Arrays wie:
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
Ergebnisse in dieser Ausgabe:
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
quelle
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.Antworten:
Mit einer Hilfsfunktion:
Der letzte Befehl im obigen Skript würde sich auf das Äquivalent des Schreibens erweitern
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 inbash
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
Das Skript würde ausgegeben
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 mit
makeself
:Das
makeself
Skript führt dies mit den Argumenten für Ihr Installationsskript aus: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.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
produziert
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 ändernin
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 .
quelle
"--$param=${inhash[$param]}"
oder in vergessen"${list[@]}"
, oder das Skript, das die Optionen erhält, hat beim Parsen etwas falsch gemacht.