在 Bash 中,我可以使用
a
实例化一个空数组 a=()
。然后我可以使用例如附加元素a[${#a[@]}]="new element"
,其中 ${#a[@]}
给出 a
中的元素数量。在 Bash 函数中:
fun() {
local a=()
echo "size: ${#a[@]}"
echo "content: >${a[@]}<"
}
fun # run the function
在现代 Bash 版本中,此打印
size: 0
content: >< # empty
对于 Bash 3.0,我明白了
size: 1
content: >()<
看起来
a
并不是真正的数组,而是一个值为 ()
的字符串。
如果删除
local
关键字,我可以获得通常的行为。这表明 Bash 3.0 不支持混合 local
和数组初始化 ()
。
这是预期的吗?
我正在编写一个大型 Bash 脚本,并寻求与低至 3.0 的所有 Bash 版本兼容。我能想到两种解决方案,但都不好:
a
已完全填充元素,如果等于 ()
,则忽略 a
的第一个元素。这(有点令人惊讶)有效,因为即使当 a
是字符串 ()
时,数组追加 a[${#a[@]}]="new element"
仍然有效,有效地将 a
转换为数组,将原始字符串值 ()
作为第一个元素。还有更好的想法吗?
为了使用 Bash 3.0 进行测试,我使用 Docker:
docker run --rm bash:3.0 bash -c 'fun() { local a=(); echo "size: ${#a[@]}"; echo "content: >${a[@]}<"; }; fun'
问题已经消失了
bash:3.1
。
将“空”数组分配给名称实际上根本不定义变量;它只是设置名称的数组属性。一些选项:
declare -a a
local a; a=()
local -a a
您所看到的似乎是
bash
3.0 的 local
实现中的一个错误(随后在 bash
3.1 中修复),无法正确识别数组分配。