Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是;如果[…]那么;(不带分号或换行符)在ksh中有效,但在bash中无效?_Bash_Shell_Ksh - Fatal编程技术网

为什么是;如果[…]那么;(不带分号或换行符)在ksh中有效,但在bash中无效?

为什么是;如果[…]那么;(不带分号或换行符)在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都会给出一个不带分号的语

我注意到KSH和Bash之间有一个区别,我正在寻找这一点的文档,或者可能是确认其中一个是bug

在Korn Shell(见KSH88和KSH93)中,此命令工作正常,并打印结果“是”:

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