我知道您可以像这样为数组创建indirect parameter expansion:
var1="target"
var2="arrayname"
targetarrayname=( "one" "two" "three" )
builtarrayname="${var1}${var2}[@]"
echo ${!builtarrayname} # prints "one two three"
但是我不知道如何添加到此间接引用,就像我通常直接使用targetarrayname+=('foo')
一样。
我尝试过:
!builtarrayname+=('foo') # gives "Syntax error near unexpected token `'foo''"
和其他一些随机分类的尝试,基本上是对此的变体。
我的预期输出是让targetarrayname
包含one two three foo
,并通过间接参数扩展做到这一点。
这可能吗?
答案 0 :(得分:3)
它避免了substantial security bugs通过printf %q
运行所有值,以确保在将它们替换为eval
内容之前可以安全地对其进行转义。
#!/bin/bash
appendToArray() {
local _targetArrayName _argumentData _cmd
_targetArrayName=$1; shift || return
printf -v _argumentData '%q ' "$@"
printf -v _cmd '%q+=( %s )' "$_targetArrayName" "$_argumentData"
eval "$_cmd"
}
target=( "first item" "second item" )
appendToArray target "third item" "fourth item"
declare -p target
...正确发出作为输出:
declare -a target=([0]="first item" [1]="second item" [2]="third item" [3]="fourth item")
#!/bin/bash
appendToArray() {
declare -n _targetArray=$1; shift
_targetArray+=( "$@" )
}
target=( "first item" "second item" )
appendToArray target "third item" "fourth item"
declare -p target
...具有相同的输出,所用的代码更少(也更简单)。
答案 1 :(得分:1)
#!/bin/bash
var1="target"
var2="arrayname"
targetarrayname=( "one" "two" "three" )
builtarrayname="${var1}${var2}[@]"
echo ${!builtarrayname} # prints "one two three"
eval "${builtarrayname:0:-3}+=( 'foo' )"
echo ${!builtarrayname} # prints "one two three foo"
请注意,尽管eval可能被认为是邪恶的:p 您需要确保只对eval语句进行了清理,以免意外执行代码。
编辑:
:0:-3
中的eval "${builtarrayname:0:-3}+=( 'foo' )"
从[@]
包含的文字字符串中删除了$builtarrayname
。由于数组的分配仅使用变量名,因此我们必须将其删除。 (read more here to see how string manipulation in variables work)
不,我认为没有评估就无法完成,因为这是在分配发生之前解析分配左侧的方式(请参见this nice answer for more info on eval。
答案 2 :(得分:0)
您可以使用printf
arrayname=()
arrayvariable=arrayname
printf -v $arrayvariable[1] "test"
echo "${arrayname[1]}"
要填充整个数组,可以使用for循环
arrayname=()
arrayvariable=arrayname
for i in {0..5}; {
item="$arrayvariable[$i]"
printf -v $item "test$i"
echo "${!item}"
}
请注意,printf
命令中的var name不需要用引号引起来,因为var name不能有空格,如果尝试在名称中添加var并带有空格,则会出现此错误
$ printf -v 'test 1' 'sef'
bash: printf: `test 1': not a valid identifier
答案 3 :(得分:0)
declare
命令将分配作为参数,在声明之前将其扩展。因此,在声明变量时可以引入任何间接级别。以下内容可在Bash 3.2中使用。
$ array=myarray
$ declare -a "$array+=(\"element 1\")"
$ echo ${myarray[0]}
element 1