“的奇怪语法是什么原因?”;案例;bash/zsh脚本中的语句?

“的奇怪语法是什么原因?”;案例;bash/zsh脚本中的语句?,bash,shell,case,zsh,Bash,Shell,Case,Zsh,从程序员的角度来看,shell脚本只是另一种编程语言,人们必须学习并遵守该语言的规则。然而,我不得不承认,这种语法是我在一种相当常用的语言中见过的最奇怪的风格。shell是否从其派生的旧语言中获取了此语法?语法中是否有特殊含义 作为一个例子,这里有一个小片段,我从 首先,我可以看到case以esac结尾,这是它的相反形式(比如if以fi结尾)。其次,我知道每个案例后面都有一个)。很公平,但我到底为什么需要两个在每条语句的末尾?我还要说,没有附带(的)的很难看 我正在寻找有关该语言历史方面的更多信

从程序员的角度来看,shell脚本只是另一种编程语言,人们必须学习并遵守该语言的规则。然而,我不得不承认,这种语法是我在一种相当常用的语言中见过的最奇怪的风格。shell是否从其派生的旧语言中获取了此语法?语法中是否有特殊含义

作为一个例子,这里有一个小片段,我从

首先,我可以看到
case
esac
结尾,这是它的相反形式(比如
if
fi
结尾)。其次,我知道每个案例后面都有一个
。很公平,但我到底为什么需要两个
在每条语句的末尾?我还要说,没有附带
)的
很难看


我正在寻找有关该语言历史方面的更多信息,但出于技术原因,我也持开放态度。

使用
的原因是单个
可以用于在一行中编写多个语句,如:

restart)
   stop; start;;
...

Bash可以接受匹配的括号:

case "$1" in
    (start)
        start
        ;;
    (stop)
        stop
        ;;

    etc.

右括号有时用在自然语言的列表中,如

1) do this
2) do that
反向关键字取自某种形式的Algol,但事实上对于交互使用来说是一个非常好的主意。它们清楚地划分了一个构造的结尾,包括if/else

例如,使用类似C的语法,在解析后:

if (condition)
    command here;
是否有
else
出现?rc是Plan 9中的一个外壳,具有更类似C的语法,它通过提供
if not
而不是
else
来解决这个问题,但它并不漂亮

使用Bourne shell语法,您将拥有
else
fi
,无需读取其他输入。

每个请求:


  • 那么,你能猜出为什么循环是“
    代表…;do…;done
    ”而不是“
    代表…;do…;od
    ”?这有一个合理的理由——但在其他地方使用了类似Algol的反向关键字来标记结束
答复:

  • 语法来自Bourne(Bourne shell的名声)。他曾在Algol上工作过,并且非常喜欢在Algol上建模一些shell语法。Algol使用反向关键字来标记构造的结尾,因此“case…esac”是合适的。循环不以“od”结尾的原因是Unix-octal dump中已经有一个命令“od”。因此,使用“done”代替
众所周知,Bourne shell的源代码是用带有宏的特殊语言编写的,使其看起来像Algol。这使得它很难维护

关于主要问题,关于为什么在
案例
陈述中的备选方案周围没有括号(括号),我有一些相关的理论

首先,早在编写Bourne shell(20世纪70年代末)时,很多编辑都是通过“
ed
”完成的。它没有跳转到平衡括号或其他类似符号的概念,因此不需要前导括号。此外,如果您正在编写文档,您可以使用以下命令封送您的参数:

a) ...blah...
b) ...more...
c) ...again...
开头的括号经常被省略,
case
语句将非常适合该模型


当然,从那时起,我们已经习惯了在键入闭括号时标记匹配的开括号的编辑器,因此旧的Bourne shell表示法很讨厌。POSIX标准使前括号成为可选的;大多数类似POSIX的shell的现代实现(Korn、Bash、Zsh)将支持这一点,我通常在不必担心到Solaris 10这样的机器的可移植性时使用它,其中/bin/sh仍然是一个忠实的Bourne shell,不允许使用前导括号(我通常使用
#!/bin/ksh
作为shebang来处理)

那么你能猜出为什么循环是“for…”do…;done”而不是“for…”do…;od“?这是有充分的理由的,但是在其他地方使用了类似Algol的反向关键字来标记结束。@Jonathan我不是在争论“为什么它是这样而不是那样?”(我想我在一开始就已经说清楚了)。我的问题更像是“丑陋的语法是从哪里来的?”语法来自伯恩(Bourne shell的名声)。他曾在Algol上工作过,并且非常喜欢在Algol上建模一些shell语法。Algol使用反向关键字来标记构造的结尾,因此“case…esac”是合适的。循环不以“od”结尾的原因是Unix-octal dump中已经有一个命令“od”。因此,使用“done”代替。(而且,众所周知,Bourne shell源代码是用特殊的宏编写的,使其看起来像Algol。这使得它很难维护。)@Jonathan good one,请回答:)POSIX和Korn shell也允许使用前导括号。很久以前,
ed
(“标准文本编辑器”-在第7版UNIX手册中是这样说的)没有“将光标反弹到匹配的开括号”选项,因此开括号并不是真正必要的。Autoconf和朋友们更喜欢在#(
)中的
之后放置一条带有适当数量的开括号的注释(例如,
大小写“$1”)。这有助于无法在
$()中处理正常case语句的shell
和编辑器就像新语法一样,但也适用于原始的Bourne shell。@丹尼斯很高兴知道,但这是在非匹配样式流行之前还是之后?@phunehehe:我不知道你的意思,除非你想知道是否有一个shell具有不接受ope的
case
/
esac
n个括号。答案是“是”。原始的Bourne shell就是一个例子。不,我的意思是,bash接受匹配的父级吗
a) ...blah...
b) ...more...
c) ...again...