С вспомогательной функцией:
#!/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[@]}"
Последняя команда в приведенном выше сценарии будет расширена до эквивалента написания
my_script.sh "--key2=value" "--key1=value1"
to_param_list
Функция принимает имя переменного массива и имя ассоциативного массива переменного и использует их , чтобы создать два «эталонное название» переменные в функции (namerefs были введены в bash
выпуске 4.3). Затем они используются для заполнения заданной переменной массива ключами и значениями в соответствующем формате из ассоциативного массива.
Цикл в функции повторяется "${!inhash[@]}"
, и это список ключей, заключенных в отдельные кавычки в вашем ассоциативном массиве.
Как только вызов функции вернется, скрипт будет использовать массив для вызова другого вашего скрипта или команды.
Запуск выше с
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
скрипт выведет
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
Это показывает, что параметры генерируются без разделения слов или ввода имени файла в действие. Это также показывает, что порядок ключей может не сохраняться, так как доступ к ключам из ассоциативного массива будет делать это в довольно случайном порядке.
Вы не можете использовать безопасную подстановку команд здесь, так как результатом будет одна строка. Если не заключено в кавычки, эта строка будет разделена на пробельные символы (по умолчанию), что дополнительно разделит и ключи, и значения вашего ассоциативного массива. Оболочка также будет выполнять поиск имени файла в результирующих словах. Двойные кавычки подстановки команд не помогли бы, так как это привело бы к вызову your my_script.sh
с одним аргументом.
Что касается вашей проблемы сmakeself
:
makeself
Скрипт делает это с аргументами к установщику сценарию:
SCRIPTARGS="$*"
Это сохраняет аргументы в виде строки в $SCRIPTARGS
(сцепленные, разделенные пробелами). Это позже вставляется в самораспаковывающийся архив как есть. Чтобы параметры были правильно проанализированы при их повторной оценке (как это происходит при запуске программы установки), вам необходимо будет указать дополнительный набор кавычек в значениях параметров, чтобы они были правильно разделены.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
Обратите внимание, что это не ошибка в моем коде. Это всего лишь побочный эффект makeself
создания шелл-кода на основе предоставленных пользователем значений.
В идеале makeself
сценарий должен был написать каждый из предоставленных аргументов с дополнительным набором кавычек вокруг них, но это не так, предположительно, потому что трудно понять, какой эффект это может иметь. Вместо этого он предоставляет пользователю дополнительные цитаты.
Перезапустив мой тест сверху, но теперь с
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
производит
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
Вы можете видеть, что эти строки при повторной оценке оболочкой не разбиваются на пробелы.
Очевидно, что вы можете использовать свой исходный ассоциативный массив и вместо этого добавить кавычки в to_param_list
функцию, изменив
outlist+=( "--$param=${inhash[$param]}" )
в
outlist+=( "--$param='${inhash[$param]}'" )
В любой из этих изменений в код будет включать в себя одиночные кавычки в значениях параметров, поэтому переоценка ценностей стала бы необходимой .
my_script.sh "$(declare -p thearray)$"
. Вmyscript.sh
вы читаете это сsource /dev/stdin <<<"$1"
Тогда у вас естьthearray
в вашем сценарии. Вы можете иметь другие аргументы рядом с массивом. Вы можете передать много переменных:my_script.sh "$(declare -p var1 var2 ...)"
в этом единственном аргументе.