$ help [
[: [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
$ shellcheck gmail-browse-msgs-algorithm.sh
In gmail-browse-msgs-algorithm.sh line 847:
[[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
^-- SC1035: You need a space after the [[ and before the ]].
最简单的解释是,因为在手册中它显示为在and和 close
[[ expression ]]
之间必须有空格。但当然,我们可以尝试更深入地研究它。Shell 的语法有些复杂,并且严重依赖“分词”的概念。特别是, ksh(1)手册指出:[[
expression
]]
因此,如手册中所述,字符序列
[[-e
被视为外壳词。ksh
将在内置命令和特殊运算符( likefor
orwhile
)列表中查找此类命令,然后查找外部命令 - 瞧 - 未找到,因此出现有关未找到命令的错误消息。在这种情况下
[[
也不是特殊的元字符。如果是,则-e
in 部分[[-e
将被视为外壳词,而不是其[[
自身的参数。但是,[[
被描述为复合命令,并且手册说如下:因此,为了
[[
被识别为复合命令,它必须是命令或命令列表的第一个单词,根据先前对“单词”的定义,这意味着它必须用空格、制表符或换行符与其他命令分隔词/论据。您在评论中问过:“为什么解析器不能在找到“[[”模式后立即停止,并将其视为条件命令的开始?” 简短的回答可能是因为 1)
[
语法的影响,因为它最初是一个外部命令,并且对于 POSIX 标准遵从性即使在今天也作为外部命令存在,以及 2) 因为 shell 解析器是这样构建的。Shell 解析器可以识别其他非空格分隔的特殊字符:echo $((2+2))
并且(echo foobar)
工作得很好。也许将来当ksh
开发恢复或出现分叉或克隆(如mksh
或pdksh
)时,有人将在[[-e
.也可以看看:
[[
称为“保留字”(参见Shell Command Language 的第 2.9 节)。根据 POSIX 定义,保留字必须用空格分隔。相比之下,运算符是运算符,第 2.9 节中的标准状态“表示包括在某些不需要s 的地方(当令牌之一是运算符时)的令牌(
之间的间距”。<blank>
请参阅相关讨论: POSIX Shell Grammar:为什么 Brace Group 需要第一个空格,但 Subshell 不需要?需要注意的是,它
[
是一个命令,bash 和 ksh 中的 shell 关键字[[
是基于[
.[[
的使用方式与[
. 有时您甚至可以在行为不变的情况下[
]
替换为。[[
]]
与[
任何命令一样,命令及其参数之间必须有空格。这同样适用于[[
。我们以前只有
/usr/bin/[
. 现在大多数 shell 都[
内置了以提高效率——但语法是相同的。在提供的shell 中,它可以[[
作为.[
以下是
[
bash 中的描述:所以
[
相当于test
(除了期待]
最后的争论)。help test
将提供更多详细信息。您可以将其与help [[
.还有一个外部命令
[
(man \[
) 的手册页。如果是
[
也不[[
是命令。完整的词[[-e
是。if [[-e
使它成为对真/假的测试。那么命令[[-e
存在吗?是的。或者没有。
[[-e
它就是这样:shell 无法理解,因此它假定它是它自己的命令。;-)空格是分隔符,是必需的。如您所见
shellcheck
:(ksh 和 bash 都支持
[[
并且没有空格就无法工作。Shellcheck 使用包含该错误行的类似 ksh 和 bash 脚本准确地给出了该输出。)为什么需要分隔符与标记和词典有关。
[[
可以是外部命令!也就是说,它可能是一个程序,而不是您的 shell 直接支持的某些语法。支持无空格语法是可能的,ksh
但在具有外部的系统上会失败,[[
因此出于兼容性原因,最好保留所需的空间。例如, BusyBox
[[
作为外部命令提供。由于
[[-e
可以参与shell扩展(它可以像为了列出所有以介于
[
和包含之间的字母开头的文件),如果并且是特殊字符不参与正常的空格管理的分词e
,那将是一团糟。[
]