循环名称参考

war*_*iuc 3 bash

我有这个脚本:

#!/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)

这是什么意思?如何解决这个问题?

4ae*_*1e1 7

让我们关注函数的第一行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" 开头的变量"),你必须拒绝不安全的输入.