我注意到 KSH 和 Bash 之间的差异,并且我正在寻找记录该差异的位置,或者可能确认其中一个是错误。
在 Korn Shell 中(在 KSH88 和 KSH93 上看到),此命令运行良好,并打印结果“yes”:
if [[ -z "" ]] then echo yes ; fi # Note no ';' after the ']]'
Run Code Online (Sandbox Code Playgroud)
在 Bash 中,我得到一个syntax error near unexpected token 'then'
.
仅当我使用双括号时才会出现此行为。如果我使用单括号形式的条件表达式,KSH 和 Bash 都会给我一个没有分号的语法错误,但会抱怨 而fi
不是then
.
这是一个错误还是一个功能?在 ksh 或 Bash 中?我注意到 Bash 和 ksh 的手册页的 语法略有不同if
,但这种差异似乎不适用于这种情况。
编辑:bash
有人(@jp48)指出了和手册页之间语法定义的显着差异ksh
。然而,查看与AST源代码匹配的 Solaris (11.3)手册页,语法为:
if list ;then list [ ;elif list ;then list ] ... [ ;else list ] ;fi
Run Code Online (Sandbox Code Playgroud)
它与 Bash 手册页的区别在于分号的位置(而不是存在)在 // 之前,elif
而else
不是fi
在list
:
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
Run Code Online (Sandbox Code Playgroud)
不带分号的备用语法来自 ksh 的公共域版本(可能是 PDksh),而不是“官方”ksh 版本。
TL;DR:根据ksh 手册页,这不是一个错误。
[
和之间的主要区别[[
在于,它[
是一个关键字,并且[[
是两个 shell 中的内置函数。请注意,出于性能原因,永远不会使用“后备可执行文件” /bin/[
(本质上是/bin/test
),但如果我们假装执行了此命令,则可以更好地理解接下来的内容。
值得注意的是,这]]
也是一个关键字,但]
只是传递给[
/ 的参数test
。
这是一些证明(两个 shell 中的输出几乎相同):
$ type [[
[[ is a shell keyword
$ type ]]
]] is a shell keyword
$ type [
[ is a shell builtin
$ type ]
***: not found
Run Code Online (Sandbox Code Playgroud)
解释完这一点后,让我们看看您的示例中会发生什么。
根据此手册页, bash 的行为符合预期(即它需要);
:
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
Run Code Online (Sandbox Code Playgroud)
然后让我们关注 ksh,作为参考,我将使用 FreeBSD 的手册页。
ksh中的语法if
如下
if list then list [elif list then list] ... [else list] fi
Run Code Online (Sandbox Code Playgroud)
以及 ksh 中的列表:
必须以分号、换行符或(语法正确的)保留字结尾
因此,[...]
without;
不是一个有效的列表(请记住,最后一个]
不是关键字也不是内置的,而是传递给 的“参数” [
)。
而[[...]]
是一个有效列表,因为]]
是一个语法正确的保留字。
总之,这不是一个错误,因为它遵循规范;;
当然,不使用(或换行符)并不是最佳实践,而且可能不符合 POSIX 标准。
归档时间: |
|
查看次数: |
2238 次 |
最近记录: |