为什么在此之后不接受分号?

Ben*_*rel 9 shell

我是 shell 编程的新手,注意到以下内容被接受:

if [ $table = "Session" ]; then
continue; fi
Run Code Online (Sandbox Code Playgroud)

以下是:

if [ $table = "Session" ]; then continue; fi
Run Code Online (Sandbox Code Playgroud)

虽然以下会产生语法错误:

if [ $table = "Session" ]; then; continue; fi
Run Code Online (Sandbox Code Playgroud)

为什么then关键字与其他关键字不同?

Mar*_*ich 14

因为then既不是命令也不是内建的 shell,而是if语法的一部分。来自man bash

   if list; then list; [ elif list; then list; ] ... [ else list; ] fi
          The  if  list is executed.  If its exit status is zero, the then
          list is executed.  Otherwise, each  elif  list  is  executed  in
          turn,  and  if  its  exit status is zero, the corresponding then
          list is executed and the command completes.  Otherwise, the else
          list  is executed, if present.  The exit status is the exit sta?
          tus of the last command executed, or zero if no condition tested
          true.
Run Code Online (Sandbox Code Playgroud)

所以这:

if [ $table = "Session" ]; then continue; fi
Run Code Online (Sandbox Code Playgroud)

之所以有效[ $table = "Session" ]continue是因为和都是可以独立使用的命令;它们构成了命令的相应list部分if。只需将它们粘贴到交互式 shell 中,您就会看到它们不会导致任何语法错误:

martin@martin:~$ export table=test
martin@martin:~$ [ $table = "Session" ]
martin@martin:~$ continue
bash: continue: only meaningful in a `for', `while', or `until' loop
Run Code Online (Sandbox Code Playgroud)

另一方面,then不是一个真正可以独立存在的命令:

martin@martin:~$ then
bash: syntax error near unexpected token `then'
Run Code Online (Sandbox Code Playgroud)

因此,在前两个示例中,您使用的if就像手册页描述的那样:

if list; then list; fi
Run Code Online (Sandbox Code Playgroud)

但是如果你把一个;放在后面thenbash就会把这看作是一个语法错误。诚然,shell 语法有时看起来很令人困惑,尤其是当您刚刚接触它时。我记得对它需要在[and周围有空格这一事实感到非常困惑],但是一旦你意识到这[实际上是一个命令或 shell 内置,它就可以理解了。:)


Gil*_*il' 7

您需要在命令后放置一个分号。[ … ]是一个命令,就像continue. 另一方面,if,thenfi不是命令:它们是保留字。

if看起来像一个命令,但那是因为它几乎总是跟随着一个命令。写是有效的

if print_table_value >foo; [ "$(cat foo)" = "Session" ]; then …
Run Code Online (Sandbox Code Playgroud)

也可以通过多种方式呈现,例如

if
  print_table_value >foo
  [ "$(cat foo)" = "Session" ]
then
…
Run Code Online (Sandbox Code Playgroud)

条件命令的一般语法是

if复合列表然后复合列表
(elif复合列表然后复合列表* 
(else复合列表然后复合列表

在哪里

  • 换行符仅用于可读性。
  • 化合物列表是命令的列表,由每个终止;或换行。
  • (……)表示可选部分,(…) *表示可以重复 0、1 或多次的部分。

关键字仅在命令的开头被识别。

条件命令必须以关键字 结尾fi。如果其他命令出现在它之后,这并不会消除操作员跟随它的需要;例如,如果条件后跟另一个命令,那么它们之间需要有一个;或换行符;如果条件要在后台执行,那么后面需要跟&,等等。