为什么bash中的数组声明周围的语音会导致它的长度为零?

时间:2014-10-17 16:37:20

标签: arrays bash

我最近在bash脚本中遇到了一个奇怪的错误。代码失败了,除以零错误。脚本除以声明的数组的长度,并且数组肯定是由字符串填充的。出于某种原因,尽管已经填充,但阵列的长度为零。下面给出了一个重现问题的示例脚本。

#!/bin/bash

aCoolFunction(){

    declare -a messageSpeechMarks="(
    'a'
    'b'
    'c'
    )";

    declare -a messageNoSpeechMarks=(
    'a'
    'b'
    'c'
    );

    for item in ${messageSpeechMarks[@]}
    do
        echo "${item}"
    done

    echo "Length of messageSpeechMarks: ${#messageSpeechMarks[@]}"
    echo "Length of messageNoSpeechMarks: ${#messageNoSpeechMarks[@]}"
}

aCoolFunction

在Linux Mint上使用GNU bash 4.3.11(1)运行时,会给出输出:

a
b
c
Length of messageSpeechMarks: 0
Length of messageNoSpeechMarks: 3

如您所见,只需从数组声明之前和之后删除语音标记即可解决问题并导致数组具有正确的长度。任何人都可以向我解释declare -a array=( ... )declare -a array="( ... )"之间的区别吗?带语音标记的声明实际上意味着什么?感谢。

1 个答案:

答案 0 :(得分:1)

可以说,应该存在以下区别:

declare a="(1 2 3)"

a="(1 2 3)"

在第二种情况下,a被设置为带引号的字符串(1 2 3),因此括号不具有语法意义。

相反,在declare语句中,可能会在执行declare之前将参数取消引用,以便declare将括号视为数组标记。但另一方面,预期很可能是

declare a=(1 2 3)

a=(1 2 3)将被视为单个声明,而不是三个单独的参数。

但是,如果参数被反引号,那么declare(或exportlocal}一个标量变量的值如何以一个左括号开头?

模糊性反映了解析bash内置函数的难度,特别是因为没有标准语法来指导我们。

zsh通过不允许在typeset声明中分配数组来回避这个问题。 ksh的工作方式与OP中报告的bash版本的工作方式相同:它以相同的方式解析a=...typeset a=...(因此在两种情况下,引号都会禁止识别括号中的数组作为数组标记。)