为什么写在一行上时;
,do
在 shell 循环之后没有一个字符?
这就是我的意思。当写在多行上时,for
循环看起来像:
$ for i in $(jot 2)
> do
> echo $i
> done
Run Code Online (Sandbox Code Playgroud)
在一行上:
$ for i in $(jot 2); do echo $i; done
Run Code Online (Sandbox Code Playgroud)
除了该行之外,所有折叠的行;
后面都有一个do
,如果包含;
,则是一个错误。可能比我聪明得多的人认为这是正确的做法是有原因的,但我不知道原因是什么。这对我来说似乎不一致。
用相同的while
循环了。
$ while something
> do
> anotherthing
> done
$ while something; do anotherthing; done
Run Code Online (Sandbox Code Playgroud)
jes*_*e_b 32
这就是命令的语法。请参阅复合命令
for name [ [in [words …] ] ; ] do commands; done
Run Code Online (Sandbox Code Playgroud)
特别注意: do commands
大多数人将do
和commands
放在单独的行上以方便阅读,但没有必要,您可以编写:
for i in thing
do something
done
Run Code Online (Sandbox Code Playgroud)
我知道这个问题是专门关于 shell 的,我已经链接到 bash 手册。它在 shell 手册中没有这样写,但在Stephen Bourne为字节杂志写的一篇文章中是这样写的。
斯蒂芬 说:
甲命令列表是由一个新行或分离或终止一个或多个简单命令的序列
;
(分号)。此外,像do和done 这样的保留字通常前面有一个换行符或;
... 每次执行do 之后的命令列表时依次执行。
ilk*_*chu 13
我不知道这种语法的最初原因是什么,但让我们考虑这样一个事实,即while
循环可以在条件部分采用多个命令,例如
while a=$(somecmd);
[ -n "$a" ];
do
echo "$a"
done
Run Code Online (Sandbox Code Playgroud)
这里,do
关键字是区分条件部分和循环主体所必需的。do
是一个像while
, if
and then
(and done
)这样的关键字,它似乎与其他关键字一致,它后面不需要分号或换行符,而是直接出现在命令之前。
替代方案(泛化为if
and while
)看起来有些难看,我们需要编写例如
if; [ -n "$a" ]; then
some command here
fi
Run Code Online (Sandbox Code Playgroud)
for
循环的语法是相似的。
Kaz*_*Kaz 11
Shell 语法是基于前缀的。它具有由特殊关键字引入的子句。某些条款必须放在一起。
一个while
循环由一个或多个测试命令组成:
test ; test ; test ; ...
Run Code Online (Sandbox Code Playgroud)
并通过一个或多个正文命令:
body ; body ; body ; ...
Run Code Online (Sandbox Code Playgroud)
有些东西必须告诉 shell 一个 while 循环开始了。这就是这个while
词的目的:
while test ; test ; test ; ...
Run Code Online (Sandbox Code Playgroud)
但接下来,事情就变得模棱两可了。哪个命令是正文的开始?有些东西必须表明这一点,这就是do
前缀的作用:
do body ; body ; body ; ...
Run Code Online (Sandbox Code Playgroud)
最后,必须有一些东西表明最后的尸体已经被看到;一个特殊的关键字可以 done
做到这一点。
这些 shell 关键字不需要分号分隔,即使在同一行也是如此。例如,如果您关闭多个嵌套循环,您可以只使用done done done ...
.
相反,... test ; body ...
如果它们在同一行,则分号介于两者之间。该分号被理解为一个终止符:它属于test
. 因此,如果do
在它们之间插入关键字,则必须在分号和 之间body
。如果它在分号的另一边,它会错误地嵌入到test
命令的语法中,而不是放在命令之间。
shell 语法最初由 Stephen Bourne 设计,并受到Algol 的启发。Bourne 非常喜欢 Algol,他在 shell 源代码中使用了大量 C 宏,使 C 看起来像 Algol。您可以从 Version 7 Unix 浏览 1979 年的 shell 源代码。宏在 中mac.h
,并且到处都在使用它们。例如,if
语句呈现为IF
... ELSE
... ELIF
... FI
。
我认为这do
在这里并不是特别特别。您收到错误,因为;
无法启动命令列表。如果是这样,第一个命令将为空,并且语法不允许空命令(变量赋值或没有命令的重定向,是的,但绝对没有,否)。在任何需要命令列表的地方,这都是正确的:
$ while true; do ; echo foo; done
dash: 1: Syntax error: ";" unexpected
$ while ; true; do; echo; done
dash: 1: Syntax error: ";" unexpected
$ { ; echo foo; }
dash: 1: Syntax error: ";" unexpected
$ if ; true; then echo foo; fi
dash: 1: Syntax error: ";" unexpected
Run Code Online (Sandbox Code Playgroud)
甚至:
$ ; ;
dash: 1: Syntax error: ";" unexpected
Run Code Online (Sandbox Code Playgroud)
在所有这些地方,都需要一个命令列表,所以一个前导;
是意外的。
归档时间: |
|
查看次数: |
5533 次 |
最近记录: |