具有辅助功能:
#!/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
这表明在生成选项时不会拆分字或文件名不起作用。它还表明,可能不会保留键的顺序,因为从关联数组中访问键会以相当随机的顺序进行操作。
您在这里不能真正安全地使用命令替换,因为它只能是一个字符串。如果不加引号,则此字符串将被分割为空白字符(默认情况下),这将另外分割关联数组的键和值。外壳程序还将对结果单词执行文件名遍历。用双引号代替命令将无济于事,因为这将导致my_script.sh
使用单个参数调用您。
关于您的问题makeself
:
该makeself
脚本使用安装程序脚本的参数来执行此操作:
SCRIPTARGS="$*"
这会将参数另存为字符串$SCRIPTARGS
(串联,用空格分隔)。稍后将其按原样插入自解压存档中。为了在重新评估选项时(在运行安装程序时)正确解析这些选项,您必须在参数值中提供一组额外的引号,以便正确定界它们。
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
请注意,这不是我代码中的错误。这只是根据用户提供的值makeself
生成shell代码的副作用。
理想情况下,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'
您会看到,当这些字符串由shell 重新评估时,不会在空格上分割。
显然,您可以使用初始的关联数组,而可以通过以下方式在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 ...)"
在此单个参数中。