Bash -v 测试在 4.3.46 中不适用于关联数组

Bash -v 测试在 4.3.46 中不适用于关联数组

版本 4.2 中引入的用于测试变量是否已设置的一元运算-v符在 bash 4.3.46 中似乎不适用于关联数组。

我有一些针对一组 bash 函数运行的 bash 测试代码,它们都在 bash 4.2(在 CentOS 7.1 上)中通过。我最近启动了 Lubuntu 16.04.1 发行版,并注意到我的大部分测试现在失败了,bash 4.3.46。似乎所有的失败都是由于这样的代码:

function is_var_set {
    local var="${1:?"No var provided to 'is_var_set'!"}"
    [[ -v "$var" ]]
}

declare -A array=(["a"]="element 1")
is_var_set "array"

这是众所周知的事情/关联数组的支持被删除了吗?

答案1

目前的bash 数组手册

如果下标已被赋值,则数组变量被视为已设置。

所以恕我直言,你必须对关联数组做一些不同的事情。我无法判断这是否是 bash 行为最近的变化。

另一种定义方法is_var_set是(ab)使用declare内置,使用以下内容:

返回状态为零,除非...其中一个名称不是有效的 shell 变量名称...

function is_var_set {
  declare -p "${1:?"No var provided to 'is_var_set'! "}" &> /dev/null
}

上面的内容适用于顶级变量名称,但不适用于任何特定的数组元素。

答案2

在 bash 版本 4.3.46 中仅有的 (旧版本(4.2)不理解此语法,新版本没有此问题)。

您需要测试一个数组,而不是(仅)测试元素 0。

[[ -v array[@] ]] 

这失败了:

$ declare -A array=(["a"]="element 1")
$ declare -p array
declare -A array=([a]="element 1" )

$ [[ -v array ]] && echo yes            # nothing is printed.

但这有效:

$ [[ -v array[@] ]] && echo yes
yes

因此,将您的功能更改为:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]]
}

使用此脚本进行测试:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]] && echo "$1 set: yes" || echo "$1 set: no"
    echo
}

var=wer
echo "array scalar $(declare -p var)"
is_var_set var

var=( foo bar baz )
echo "var indexed array $(declare -p var)"
is_var_set var

unset var
echo "var associative array $(declare -p var)"
is_var_set var

declare -A var=(["a"]="element 1")
echo "var associative array $(declare -p var)"
is_var_set var

declare -A var=(["a"]="")
echo "var associative array $(declare -p var)"
is_var_set var

相关内容