声明空数组并将其与bash中的空值区分开来

声明空数组并将其与bash中的空值区分开来,bash,Bash,在运行脚本之前,我需要测试是否设置了某些环境变量。我使用的技术来自: if[-z${var1+x}] 回显“var1未设置” 出口1 fi 这适用于字符串变量,但有一个参数需要是数组。它必须设置,但可以为空 foo=(“foo”“bar”“baz”) [-z${foo+x}]#错误 bar=() [-z${bar+x}]#正确 [-z${baz+x}]#同样正确 所以,我的问题是如何声明一个空数组,使其与未设置的变量不同。我还想测试变量是数组(是否为空)还是非数组(是否为设置的)。您可以使用

在运行脚本之前,我需要测试是否设置了某些环境变量。我使用的技术来自:

if[-z${var1+x}]
回显“var1未设置”
出口1
fi
这适用于字符串变量,但有一个参数需要是数组。它必须设置,但可以为空

foo=(“foo”“bar”“baz”)
[-z${foo+x}]#错误
bar=()
[-z${bar+x}]#正确
[-z${baz+x}]#同样正确

所以,我的问题是如何声明一个空数组,使其与未设置的变量不同。我还想测试变量是数组(是否为空)还是非数组(是否为设置的)。

您可以使用
declare-p
找出变量的类型

scalar=1
declare -p scalar  # declare -- scalar="1"
arr=(1 2 3)
declare -p arr     # declare -a arr=([0]="1" [1]="2" [2]="3")
未声明的变量将以值1退出:

unset arr
declare -p arr  # bash: declare: arr: not found
echo $?         # 1
要测试数组是否为空,请测试
${arr[@]}

arr=(1 2 3)
echo ${#arr[@]}  # 3
arr=()
echo ${#arr[@]}  # 0

可以使用declare-p检查变量类型

$ list=()
$ declare -p list
declare -a list='()'
如果输出包含“-a”,则var是一个数组,即使是空的,也可以使用此方法

[[ ${var[@]@A} =~ '-a' ]] && echo array || echo variable
基于此,

$ man bash
...
       ${parameter@operator}
              Parameter transformation.  The expansion is either a transformation of the value of parameter or information about parameter itself, depending
              on the value of operator.  Each operator is a single letter:

              Q      The expansion is a string that is the value of parameter quoted in a format that can be reused as input.
              E      The expansion is a string that is the value of parameter with backslash escape sequences expanded as with the $'...' quoting mechansim.
              P      The expansion is a string that is the result of expanding the value of parameter as if it were a prompt string (see PROMPTING below).
              A      The  expansion  is  a string in the form of an assignment statement or declare command that, if evaluated, will recreate parameter with
                     its attributes and value.
              a      The expansion is a string consisting of flag values representing parameter's attributes.

              If parameter is @ or *, the operation is applied to each positional parameter in turn, and the expansion is the resultant list.  If  parameter
              is  an  array variable subscripted with @ or *, the case modification operation is applied to each member of the array in turn, and the expan‐
              sion is the resultant list.

              The result of the expansion is subject to word splitting and pathname expansion as described below.
...

[-z${bar+x}]
返回true。你确定你测试了所有这些命令吗?@oguzismail对我来说,它返回false。您使用的是bash还是其他shell?我使用的是bash5.0.11。所以你是说,
unset xxx;[-z${xxx+x}]&&echo true
不会在您的shell上打印任何内容?@oguzismail是的,您是对的,我更新了我的问题,所以现在它是正确的。我所说的
true
是指“变量已设置”,当我想到它时,这肯定会误导我,为了测试它,我必须做一些类似
的事情,如果[[$(declare-p var1)=~“-a”]
?我是按照
[!$(declare-p var1 2>/dev/null | | true)=~“-a”]
,这样,当未设置
var1
且不提供错误消息时,它不会下降。很难看,但很管用。接球不错。我原以为它会返回错误代码并导致错误,但它是多余的。这如何区分空数组和未设置变量?