Con una función 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[@]}"
El comando final en el script anterior se expandiría al equivalente de haber escrito
my_script.sh "--key2=value" "--key1=value1"
La to_param_list
función toma el nombre de una variable de matriz y el nombre de una variable de matriz asociativa y los utiliza para crear dos variables de "referencia de nombre" en la función (se introdujeron namerefs en la bash
versión 4.3). Estos se utilizan para llenar la variable de matriz dada con las claves y los valores en el formato apropiado de la matriz asociativa.
El ciclo en la función se repite "${!inhash[@]}"
, que es la lista de claves citadas individualmente en su matriz asociativa.
Una vez que la llamada a la función regresa, el script usaría la matriz para llamar a su otro script o comando.
Ejecutando lo anterior con
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
el script saldría
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
Esto muestra que las opciones se generan sin la división de palabras o el efecto de bloqueo de nombre de archivo. También muestra que el orden de las claves puede no conservarse, ya que acceder a las claves desde una matriz asociativa lo hará en un orden bastante aleatorio.
Realmente no puede usar una sustitución de comando de forma segura aquí, ya que el resultado sería una sola cadena. Si no se cita, esta cadena se dividiría en caracteres de espacio en blanco (por defecto), lo que dividiría adicionalmente tanto las claves como los valores de su matriz asociativa. El shell también llevaría a cabo el bloqueo de nombre de archivo en las palabras resultantes. Citar dos veces la sustitución del comando no ayudaría, ya que eso resultaría en llamarlo my_script.sh
con un solo argumento.
Con respecto a su problema conmakeself
:
El makeself
script hace esto con los argumentos de su script de instalación:
SCRIPTARGS="$*"
Esto guarda los argumentos como una cadena en $SCRIPTARGS
(concatenados, separados por espacios). Esto luego se inserta en el archivo autoextraíble tal cual. Para que las opciones se analicen correctamente cuando se vuelven a evaluar (que son cuando se ejecuta el instalador), deberá proporcionar un conjunto adicional de comillas en los valores de los parámetros para que se delimiten correctamente.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
Tenga en cuenta que esto no es un error en mi código. Es solo un efecto secundario de makeself
producir código shell basado en valores proporcionados por el usuario.
Idealmente, el makeself
script debería haber escrito cada uno de los argumentos proporcionados con un conjunto adicional de citas a su alrededor, pero no lo hace, presumiblemente porque es difícil saber qué efecto puede tener. En cambio, le deja al usuario proporcionar estas citas adicionales.
Volver a ejecutar mi prueba desde arriba, pero ahora 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'
Puede ver que estas cadenas, cuando son reevaluadas por el shell, no se dividirían en espacios.
Obviamente, podría usar su matriz asociativa inicial y en su lugar agregar las comillas en la to_param_list
función cambiando
outlist+=( "--$param=${inhash[$param]}" )
dentro
outlist+=( "--$param='${inhash[$param]}'" )
Cualquiera de estos cambios en su código incluiría las comillas simples en los valores de las opciones, por lo que sería necesaria una reevaluación de los valores .
my_script.sh "$(declare -p thearray)$"
. Enmyscript.sh
lo lees consource /dev/stdin <<<"$1"
Entonces lo tienesthearray
en tu guión. Puede tener otros argumentos junto con la matriz. Puede pasar muchas variables:my_script.sh "$(declare -p var1 var2 ...)"
en este único argumento.