Con una funzione di aiuto:
#!/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[@]}"
Il comando finale nello script sopra si espanderebbe all'equivalente di aver scritto
my_script.sh "--key2=value" "--key1=value1"
La to_param_list
funzione prende il nome di una variabile di array e il nome di una variabile di array associativo e li usa per creare due variabili di "riferimento al nome" nella funzione (sono state introdotte namerefs nella bash
versione 4.3). Questi vengono quindi utilizzati per popolare la variabile matrice fornita con le chiavi e i valori nel formato appropriato dalla matrice associativa.
Il ciclo nella funzione scorre ripetutamente "${!inhash[@]}"
, che è l'elenco delle chiavi citate individualmente nell'array associativo.
Una volta restituita la chiamata di funzione, lo script utilizza l'array per chiamare l'altro script o comando.
Eseguendo quanto sopra con
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
lo script verrebbe prodotto
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
Questo dimostra che le opzioni sono generate senza dividere le parole o rendere effettivi i globbing del nome file. Mostra anche che l'ordine delle chiavi potrebbe non essere preservato poiché l'accesso alle chiavi da un array associativo lo farà in un ordine abbastanza casuale.
Non è possibile utilizzare una sostituzione di comando in modo sicuro qui poiché il risultato sarebbe una singola stringa. Se non quotato, questa stringa verrebbe quindi suddivisa su caratteri di spazi bianchi (per impostazione predefinita), che dividerebbe ulteriormente sia le chiavi che i valori dell'array associativo. La shell eseguirà anche il globbing del nome file sulle parole risultanti. La doppia citazione della sostituzione del comando non sarebbe di aiuto in quanto ciò comporterebbe la chiamata my_script.sh
con un singolo argomento.
Per quanto riguarda il tuo problema conmakeself
:
Lo makeself
script fa questo con gli argomenti dello script del programma di installazione:
SCRIPTARGS="$*"
Questo salva gli argomenti come una stringa in $SCRIPTARGS
(concatenati, separati da spazi). Successivamente viene inserito così com'è nell'archivio autoestraente. Affinché le opzioni vengano analizzate correttamente quando vengono rivalutate (come lo sono quando si esegue il programma di installazione), sarà necessario fornire una serie aggiuntiva di virgolette nei valori dei parametri per poter essere correttamente delimitate.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
Nota che questo non è un bug nel mio codice. È solo un effetto collaterale della makeself
produzione di codice shell basato sui valori forniti dall'utente.
Idealmente, lo makeself
script avrebbe dovuto scrivere ciascuno degli argomenti forniti con un set aggiuntivo di virgolette attorno a loro, ma non lo è, presumibilmente perché è difficile sapere quale effetto potrebbe avere. Al contrario, lascia all'utente la possibilità di fornire questi preventivi aggiuntivi.
Rieseguendo il mio test dall'alto, ma ora con
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
produce
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
Si può vedere che queste stringhe, se rivalutate dalla shell, non verrebbero divise sugli spazi.
Ovviamente, potresti usare il tuo array associativo iniziale e invece aggiungere le virgolette nella to_param_list
funzione cambiando
outlist+=( "--$param=${inhash[$param]}" )
in
outlist+=( "--$param='${inhash[$param]}'" )
Ognuna di queste modifiche al codice includerebbe le virgolette singole nei valori delle opzioni, quindi sarebbe necessaria una rivalutazione dei valori .
my_script.sh "$(declare -p thearray)$"
. Inmyscript.sh
tu lo leggi consource /dev/stdin <<<"$1"
Poi haithearray
nella tua sceneggiatura. Puoi avere altri argomenti a fianco dell'array. Puoi passare molte variabili:my_script.sh "$(declare -p var1 var2 ...)"
in questo singolo argomento.