我正在尝试编写一个函数,该函数使用传入的名称写入数组。给出以下 bash 函数:
function writeToArray {
local name="$1"
echo "$name"
declare -a "$name"
${name[0]}="does this work?"
}
像这样运行:
writeToArray $("test")
我收到两个错误:
bash: declare: `': not a valid identifier
=does this work?: command not found
我期望能够做到这一点:
writeToArray $("test")
for item in "${test[@]}"; do
echo "item"
echo "$item"
done
这应该打印:
item
does this work?
我如何正确配置它来写入数组(test
在示例中命名,以便该命名的数组test
在函数外部可读)?
答案1
您可以使用 nameref 来实现:
writeToArray() {
local -n writeToArray_name="$1"
writeToArray_name[0]="does this work?"
}
测试:
bash-5.0$ test[123]=qwe
bash-5.0$ writeToArray test
bash-5.0$ typeset -p test
declare -a test=([0]="does this work?" [123]="qwe")
bash
对于还没有 namerefs的旧版本,您可以使用eval
:
writeToArray() {
eval "$1[0]='does this work?'"
}
当writeToArray
使用test
参数调用时,作为参数eval
传递test[0]='does this work?'
,然后eval
作为 shell 语言中的代码进行调用,其中它分配does this work?
给数组索引 0 的元素test
(也适用于关联数组;标量变量被转换为数组) 。
请注意,这$("test")
是捕获和扩展命令输出test
并在列表上下文中 split+glob 的语法。test
(又名[
)在未传递任何参数时不会产生任何输出),因此$("test")
扩展为空字符串,并且 split+glob 不会给你任何结果。
在这里,这是姓名您想要传递给的变量writeToArray
,因此test
,不是它的内容("$test"
),也不是同名命令的输出( ),更不用说与您的尝试"$(test)"
一样受到 split+glob 影响的同名命令的输出了。$("test")