En un script tengo una matriz asociativa como:
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
¿Hay un solo comando para transformar eso en una lista de parámetros en el formulario
--key1=value1 --key2=value2
sin tener que volver a escribir manualmente
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
El caso de uso que tenía en mente era pasar la matriz a un script como una lista de parámetros, como
my_script.sh $(to_param_list $VARS)
Para ampliar el comentario que hice sobre la respuesta de @Kusalananda, mi caso de uso exacto es el siguiente: tengo un script que se usa para construir un instalador autoextraíble usando makeelf, y este script recibe algunos parámetros que se deben separar:
- parámetros para el script en sí
- parámetros para el instalador dentro del instalador autoextraíble
Los scripts luego compilan el instalador de esta manera:
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[@]}"
Sin embargo, he probado el paso del parámetro con un script de instalación muy simple dentro del paquete:
while ! -z "$1" ; do
echo "$1"
shift
done
y pasando una matriz como:
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
da como resultado esta salida:
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
bash
parameter
associative-array
Matteo Tassinari
fuente
fuente
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.Respuestas:
Con una función auxiliar:
El comando final en el script anterior se expandiría al equivalente de haber escrito
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 labash
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
el script saldría
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 con
makeself
:El
makeself
script hace esto con los argumentos de su script de instalación: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.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
produce
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 cambiandodentro
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 .
fuente
"--$param=${inhash[$param]}"
o adentro"${list[@]}"
, o el script que recibe las opciones hace algo mal al analizarlas.