为什么是;如果[…]那么;(不带分号或换行符)在ksh中有效,但在bash中无效?
我注意到KSH和Bash之间有一个区别,我正在寻找这一点的文档,或者可能是确认其中一个是bug 在Korn Shell(见KSH88和KSH93)中,此命令工作正常,并打印结果“是”:为什么是;如果[…]那么;(不带分号或换行符)在ksh中有效,但在bash中无效?,bash,shell,ksh,Bash,Shell,Ksh,我注意到KSH和Bash之间有一个区别,我正在寻找这一点的文档,或者可能是确认其中一个是bug 在Korn Shell(见KSH88和KSH93)中,此命令工作正常,并打印结果“是”: if [[ -z "" ]] then echo yes ; fi # Note no ';' after the ']]' 在Bash中,我在意外标记“then”附近遇到了一个语法错误 只有在使用双括号时,才会出现这种行为。如果我使用单括号形式的条件表达式,KSH和Bash都会给出一个不带分号的语
if [[ -z "" ]] then echo yes ; fi # Note no ';' after the ']]'
在Bash中,我在意外标记“then”附近遇到了一个语法错误
只有在使用双括号时,才会出现这种行为。如果我使用单括号形式的条件表达式,KSH和Bash都会给出一个不带分号的语法错误,但会抱怨fi
而不是then
这是一个bug还是一个特性?用ksh还是Bash?我注意到Bash和ksh的手册页对if的语法略有不同,但这种差异似乎不适用于这种情况
Edit:有人(@jp48)指出了
bash
和ksh
手册页在语法定义上的显著差异。但是,看看与AST匹配的Solaris(11.3),语法是:
if list ;then list [ ;elif list ;then list ] ... [ ;else list ] ;fi
这与Bash手册页之间的区别在于分号在elif
/else
/fi
之前的位置(而不是在列表之后):
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
没有分号的替代语法来自ksh的公共域版本(可能是PDksh),而不是“官方”ksh版本。好吧,它们实际上不是同一个shell,所以如果它们的反应不同,你不能称之为bug:-)
对于bash
,在man
页面中清楚地说明了这一点,在then
之前肯定有一个分号:
if列表;然后列出;[elif list;然后list;]。。。[其他列表;]fi
在我的ksh
man
页面中也有类似的一行,因此,如果我被迫选择一行作为行为不端的原因,那就是ksh
。但我还没有深入研究它,看看是否有其他的选择可能会影响这一点。粗略地看一眼就可以看出(两种情况下)换行符可以代替分号
但是,底线是,如果您按照所描述的语法进行操作,就不会有任何问题。TL;医生:根据医生的说法,这不是一只虫子
[
和[
之间的主要区别在于[
是一个关键字,[
是两个shell中的一个内置项。请注意,“回退可执行”/bin/[/code>(本质上是/bin/test
)从未出于性能原因使用过,但如果我们假设此命令已执行,则可以更好地理解下面的内容
然后值得注意的是,]
也是一个关键字,但]
只是传递给[
/测试的一个参数
以下是一些证据(两个shell中的输出几乎相同):
在解释了这一点之后,让我们看看在您的示例中发生了什么
bash的行为与预期相符(即它需要;
):
然后让我们关注ksh,作为参考,我将使用FreeBSD的
ksh中if
的语法如下
if list then list [elif list then list] ... [else list] fi
以及ksh中的列表:
必须以分号、换行符或结尾(语法正确)
保留字
因此,不带,
的[…]
不是有效的列表(请记住,最后一个]
不是关键字或内置项,而是传递给[
的“参数”)
而[…]]
是有效的列表,因为]
是语法正确的保留字
总之,它不是一个bug,因为它遵守规范;当然,不使用;
(或换行符)也不是最佳实践,而且可能不符合POSIX。6句话及其TL;DR:
适合您?回答得好,但我没有提到不阅读。“TL;DR”只有第一行:)。我在发送后倾向于编辑很多内容,我的错误…这很有道理,我只是在挠头。在回答上付出了很大的努力,正确,投了赞成票,但是TL;DR:wtf?:)
啊,“TL;DR”这一部分应该是一个快速总结,针对的是那些不关心阅读整个内容的人,而不是我自己,lol。来源:我在看Solaris手册页(),其中if
的语法包括分号。ksh源代码树中ksh手册页的源代码也是如此()。您引用的手册页似乎来自PDksh,或者是OpenBSD发布的任何东西。@charles duffy:我很感谢您尝试澄清问题标题,但我所描述的情况并不是当使用测试作为if
的一部分时,而是仅当使用[
-]]
construct.Oops——非常正确。更正了标题(同时保持其特定于所讨论的语法,而不是完全通用的“解析差异”)。
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
if list then list [elif list then list] ... [else list] fi