在 Bash 测试中是否声明了关联数组

问题描述 投票:0回答:4

如何测试 Bash 中是否声明了关联数组?我可以测试一个变量,例如:

[ -z $FOO ] && echo nope

但我似乎不适用于关联数组:

$ unset FOO
$ declare -A FOO
$ [ -z $FOO ] && echo nope
nope
$ FOO=([1]=foo)
$ [ -z $FOO ] && echo nope
nope
$ echo ${FOO[@]}
foo

编辑:

谢谢您的回答,两者似乎都有效,所以我让速度决定:

$ cat test1.sh
#!/bin/bash
for i in {1..100000}; do
    size=${#array[@]}
    [ "$size" -lt 1 ] && :
done
$ time bash test1.sh #best of five

real    0m1.377s
user    0m1.357s
sys     0m0.020s

另一个:

$ cat test2.sh
#!/bin/bash

for i in {1..100000}; do
    declare -p FOO >/dev/null 2>&1 && :
done
$ time bash test2.sh #again, the best of five

real    0m2.214s
user    0m1.587s
sys     0m0.617s

编辑2:

让我们将切普纳的解决方案与之前的解决方案进行速度比较:

#!/bin/bash

for i in {1..100000}; do
    [[ -v FOO[@] ]] && :
done
$ time bash test3.sh #again, the best of five

real    0m0.409s
user    0m0.383s
sys     0m0.023s

嗯,速度很快。

再次感谢大家。

bash associative-array
4个回答
20
投票

bash
4.2 或更高版本中,您可以使用
-v
选项:

[[ -v FOO[@] ]] && echo "FOO set"

请注意,在任何版本中,使用

declare -A FOO

实际上并不立即创建关联数组;它只是在名称

FOO
上设置一个属性,允许您将其作为关联数组分配给该名称。在第一次赋值之前,数组本身并不存在。


13
投票

您可以使用

declare -p
检查变量是否已声明:

declare -p FOO >/dev/null 2>&1 && echo "exists" || echo "nope"

并检查具体关联数组:

[[ "$(declare -p FOO 2>/dev/null)" == "declare -A"* ]] &&
   echo "array exists" || echo "nope"

7
投票

这是社区 Wiki 版本的 @user15483624 的一个优秀答案,该问题现已作为重复项关闭。如果该用户选择在此处添加自己的答案,则应将其删除,以支持带有其名字的答案。


仅当需要与 bash 4.x 及更早版本兼容时,才应使用此问题的先前答案。在 bash 5.0 及更高版本中,可以直接使用扩展来检查变量类型;它的使用比解析

declare -p

 的输出要高效得多,并且还避免了其他提案的一些意想不到的副作用..

以下可以用来测试bash变量是否是关联数组。

[[ ${x@a} = A ]]

${x@a}

 也可以用来测试它是否是变量和数组。

$ declare x; echo "${x@a}" $ declare -a y; echo "${y@a}" a $ declare -A z; echo "${z@a}" A
    

2
投票
最简单的方法之一是检查数组的大小:

size=${#array[@]} [ "$size" -lt 1 ] && echo "array is empty or undeclared"
您可以在命令行上轻松测试:

$ declare -A ar=( [key1]=val1 [key2]=val2 ); echo "szar: ${#ar[@]}" szar: 2
此方法允许您测试数组是否已声明且为空或完全未声明。空数组和未声明的数组都将返回 

0

 大小。

注意: 如果使用 set -e

set -u
,请确保您了解使用 
set -eset -u 的后果。

© www.soinside.com 2019 - 2024. All rights reserved.