为什么"如果[[...]]那么" (没有分号或换行符)在ksh中有效但不是bash?

时间:2018-01-05 04:55:26

标签: bash shell ksh

我注意到KSH和Bash之间存在差异,我正在寻找记录的位置,或者确认其中一个是错误。

在Korn Shell中(见于KSH88和KSH93),此命令工作正常,结果"是"打印出来:

if [[ -z "" ]] then echo yes ; fi       # Note no ';' after the ']]'

在Bash中,我得到了syntax error near unexpected token 'then'

仅当我使用双括号时才会出现此行为。如果我使用单括号形式的条件表达式,KSH和Bash都会在没有分号的情况下给出语法错误,但会抱怨fi而不是then

这是一个错误还是一个功能?在ksh还是Bash?我注意到Bash和ksh的手册页对if的语法略有不同,但这种差异似乎并不适用于这种情况。

编辑:有人(@ jp48)指出了bashksh手册页之间语法定义的重大差异。但是,查看与AST man page匹配的Solaris(11.3)source code,语法为:

if list ;then list [ ;elif list ;then list ] ... [ ;else list ] ;fi

它与Bash手册页之间的区别在于elif / else / fi之前的分号的放置(不是存在),而不是{{1}之后的分号}:

list

没有分号的替代语法来自公共域版本的ksh(可能是PDksh),而不是"官方" ksh release。

2 个答案:

答案 0 :(得分:4)

TL; DR:根据ksh man page,不是错误。

[[[之间的区别在于[是一个关键字,而[[是两个shell中内置的。请注意"后备可退出" /bin/[(基本上是/bin/test)从不出于性能原因而使用,但如果我们假装执行此命令,则可以更好地理解后面的内容。

值得注意的是,]]也是关键字,但]只是传递给[ / test的参数。

这是一些证明(两个炮弹的输出几乎相同):

$ type [[
[[ is a shell keyword
$ type ]]
]] is a shell keyword
$ type [
[ is a shell builtin
$ type ]
***: not found

解释了这个后,让我们看看你的例子中会发生什么。

bash根据此man page按预期行事(即要求 ;):

if list; then list; [ elif list; then list; ] ... [ else list; ] fi

让我们专注于ksh,作为参考,我将使用FreeBSD' s man page

ksh中if的语法如下

if list then list [elif list then list] ... [else list] fi

ksh中的列表:

  

必须以分号,换行符或(语法正确)结尾   保留字

所以[...]没有;不是有效的列表(请记住,最后一个]不是关键字也不是内置的,而是&#34 ;参数"传递给[)。

[[...]]是有效的列表,因为]]语法正确的保留字

总之,它不是一个错误,因为它遵守规范;当然,最好不要使用;(或换行符),也可能不符合POSIX。

答案 1 :(得分:2)

好吧,他们并非实际上相同的shell,所以如果他们的反应不同,你就无法将其称为错误: - )

对于import groovy.transform.* abstract class BaseEntity { Long id String refId } @TupleConstructor(includeSuperProperties=true) @ToString(includeSuperProperties=true) class GroceryItem extends BaseEntity { String name Integer quantity } def item = new GroceryItem(1L,'067e6162-3b6f-4ae2-a171-2470b63dff00', 'Cheese Wedges', 4) println item.toString() ,它在bash页面中明确说明,man之前最明显是分号:

  

then

我的if list; then list; [ elif list; then list; ] ... [ else list; ] fi ksh页面中也有类似的行,因此,如果我强制选择一个行为不端,那么它将是{{ 1}}。但我还没有深入研究它是否有其他选择可能会影响这一点。粗略一瞥只是说明(换句)新行可以替代分号。

但是,最重要的是,如果你按照所描述的语法进行操作,你就不应该有任何问题。