从程序员的角度来看,shell脚本只是另一种编程语言,必须学习并遵守语言规则。但是,我必须承认,这种语法是我在一种常用语言中见过的最奇怪的风格。 shell是否采用了它来自的较旧语言的语法?语法中是否有特殊含义/含义?
举个例子,这是我在{<3}}上从SO
获取的一个小片段case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
check_status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
考虑到这一点,首先我可以看到case
以esac
结尾,这是其反转形式(如if
以fi
结尾)。其次,我了解每个案例后跟)
。很公平,但为什么我在每个陈述的末尾都需要两个;
?我还要说)
没有伴随(
是丑陋的。
我正在寻找有关该语言历史方面的更多信息,但我也是出于技术原因而开放。
答案 0 :(得分:37)
按要求:
for ...; do ...; done
'而不是'for ...; do ...; od
'?这有一个合理的理由 - 但在其他地方使用了标记结尾的类似Algol的反向关键字。答案:
通过声誉,Bourne shell源代码是用特殊的C语言编写的宏,使其看起来像Algol。这使得难以维护。
关于主要问题 - 关于为什么case
陈述中的替代方案没有开括号(括号) - 我有几个相关的理论。
首先,回到编写Bourne shell时(20世纪70年代末),使用“ed
”,standard text editor进行了大量编辑。它没有跳过平衡括号或其他此类符号的概念,因此不需要前导括号。此外,如果您正在编写文档,则可以使用以下方法编组您的参数:
a) ...blah...
b) ...more...
c) ...again...
通常省略左括号 - case
语句非常适合该模型。
当然,从那时起,我们已经习惯于在键入右括号时标记匹配的左括号的编辑器,因此旧的Bourne shell表示法是一种麻烦。 POSIX标准使前导括号可选;大多数类似POSIX的shell(Korn,Bash,Zsh)的现代实现都会支持它,当我不必担心像Solaris 10这样的机器的可移植性时我通常会使用它,其中/ bin / sh仍然是忠实的Bourne shell不允许前导括号。 (我通常使用#!/bin/ksh
作为shebang来解决这个问题。)
答案 1 :(得分:23)
使用;;
的原因是可以使用单个;
在一行中写入多个语句,例如:
restart)
stop; start;;
...
答案 2 :(得分:11)
Bash可以接受匹配的括号:
case "$1" in
(start)
start
;;
(stop)
stop
;;
etc.
答案 3 :(得分:3)
右括号有时在自然语言的列表中使用,例如
1) do this
2) do that
反向关键字取自某种形式的Algol,但实际上是交互式使用的一个非常好的主意。它们清楚地划分了构造的结尾,包括if / else。
例如,使用类似C的语法,在解析之后:
if (condition)
command here;
是否有else
即将到来? rc,来自Plan 9的shell,具有更像C语法,通过提供if not
代替else
来解决这个问题,但它并不漂亮。
使用Bourne shell语法,您将拥有else
或fi
,并且无需阅读其他输入。