我注意到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)指出了bash
和ksh
手册页之间语法定义的重大差异。但是,查看与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。
答案 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}}。但我还没有深入研究它是否有其他选择可能会影响这一点。粗略一瞥只是说明(换句)新行可以替代分号。
但是,最重要的是,如果你按照所描述的语法进行操作,你就不应该有任何问题。