在Bash测试中,如果声明了关联数组

Jam*_*own 11 bash associative-array

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

[ -z $FOO ] && echo nope
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:

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

$ 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
Run Code Online (Sandbox Code Playgroud)

和另外一个:

$ 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
Run Code Online (Sandbox Code Playgroud)

编辑2:

让我们快速比较Chepner的解决方案与之前的解决方案:

#!/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
Run Code Online (Sandbox Code Playgroud)

那很快.

伙计们,再次感谢

che*_*ner 10

bash4.2或更高版本中,您可以使用以下-v选项:

[[ -v FOO[@] ]] && echo "FOO set"
Run Code Online (Sandbox Code Playgroud)

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

declare -A FOO
Run Code Online (Sandbox Code Playgroud)

实际上并不会立即创建关联数组; 它只是在名称上设置一个属性FOO,允许您将名称指定为关联数组.在第一次分配之前,数组本身不存在.

  • 它不起作用。`$声明-A FOO; [[ -v FOO[@] ]] && echo "FOO set"` 从不运行 "echo"。bash 4.4.x (3认同)
  • 这并不能确定“FOO”是否是关联数组——对于数字索引数组,它也会以相同的方式返回。 (3认同)

anu*_*ava 8

您可以declare -p用来检查是否已声明变量:

declare -p FOO >/dev/null 2>&1 && echo "exists" || echo "nope"
Run Code Online (Sandbox Code Playgroud)

并特别检查关联数组:

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

  • @Jani 不确定你在说什么。如果变量没有被设置,declare 将返回一个非零退出状态(与 `help` 命令声称的相反)。@anubhava 在第二个例子中似乎有一个错字(我认为应该是 `2>/dev/null`)。否则,如果您想检测名称是否被声明为关联数组,这似乎是唯一有效的答案。 (2认同)
  • 此解决方案正在工作。谢谢!(顺便说一句,“选定”答案不是...) (2认同)

Cha*_*ffy 7

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


仅当需要与 bash 4.x 及更早版本兼容时,才应使用此问题的先前答案。在 bash 5.0 及更高版本中,可以直接使用扩展来检查变量类型;它的使用比解析 的输出要高效得多declare -p,并且还避免了其他提案的一些意想不到的副作用。

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

[[ ${x@a} = A ]]
Run Code Online (Sandbox Code Playgroud)

${x@a}也可以用来测试它是否是变量和数组。

$ declare x; echo "${x@a}"

$ declare -a y; echo "${y@a}"
a
$ declare -A z; echo "${z@a}"
A
Run Code Online (Sandbox Code Playgroud)

  • 请注意,“${z@a}”扩展为属性的**列表**,其中还可能包含其他属性,例如“r”表示只读,“x”表示导出等。 (2认同)