我有这个脚本:
#!/bin/bash
function contains() {
local -n array=$1
local value=$2
for item in "${array[@]}"; do
[ "$item" = "$value" ] && return 0
done
return 1
}
array=(a "b c" "d")
value="b c"
contains array value
Run Code Online (Sandbox Code Playgroud)
运行它我收到此错误:
***: line 6: warning: array: circular name reference
Run Code Online (Sandbox Code Playgroud)
这是什么意思?如何解决这个问题?
让我们关注函数的第一行contains
:
local -n array=$1
Run Code Online (Sandbox Code Playgroud)
当一个人执行
contains array value
Run Code Online (Sandbox Code Playgroud)
$1
设置为array
,所以local
命令在扩展后变为
local -n array=array
Run Code Online (Sandbox Code Playgroud)
其中循环引用很明显.
这是一个没有完美解决方案的已知问题(参见BashFAQ/048中的"bash名称引用的问题").我会建议那里有什么建议:
[T]这里没有我们可以给名称参考的安全名称.如果调用者的变量恰好具有相同的名称,那么我们就搞砸了.
...
现在,尽管存在这些缺点,该
declare -n
功能仍是朝着正确方向迈出的一步.但是你必须小心选择调用者不会使用的名称(这意味着你需要对调用者进行一些控制,如果只是说"不要使用以_my_pkg
" 开头的变量"),你必须拒绝不安全的输入.