Передать ассоциативный массив в качестве списка параметров в сценарий

Авторитетный ответ потребует удобного осциллографа и знания сигнализации RS-232 (к счастью, умирающее искусство).

Специальный подход состоит в том, чтобы настроить и протестировать эмулятор кабеля и терминала (в режиме DCE) с заведомо работающей системой, а затем попробовать это с вашей неисправной системой. Для получения дополнительных сведений см. Сервер Sun Fire V440 Руководство администратора, «Как получить доступ к системной консоли через сервер терминалов», стр. 59 .

8
16.03.2019, 14:47
1 ответ

Со вспомогательной функцией:

#!/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принимает имя переменной-массива и имя ассоциативной переменной-массива и использует их для создания двух переменных «ссылка на имя» в функции (nameref были введены в 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

Это показывает, что параметры генерируются без разделения слов или подстановки имен файлов. Это также показывает, что порядок ключей может не сохраняться, поскольку доступ к ключам из ассоциативного массива будет выполняться в довольно случайном порядке.


Здесь нельзя безопасно использовать подстановку команд, так как в результате получится одна строка. Если не использовать кавычки, эта строка будет разделена на пробельные символы (по умолчанию ), что дополнительно разделит как ключи, так и значения вашего ассоциативного массива. Оболочка также будет выполнять подстановку имени файла для полученных слов. Двойное цитирование подстановки команды не поможет, так как это приведет к вызову вашего 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]}'" )

Любое из этих изменений в вашем коде будет включать в себя одинарные кавычки в значениях параметров, поэтому -оценка значений станет необходимой .

14
27.01.2020, 20:11

Теги

Похожие вопросы