Warum wird danach kein Semikolon mehr akzeptiert?

8

Ich bin neu in der Shell-Programmierung und habe festgestellt, dass Folgendes akzeptiert wird:

if [ $table = "Session" ]; then
continue; fi

Und so ist das Folgende:

if [ $table = "Session" ]; then continue; fi

Während das Folgende einen Syntaxfehler erzeugt:

if [ $table = "Session" ]; then; continue; fi

Warum unterscheidet sich das thenSchlüsselwort von den anderen?

Benjamin
quelle
Das scheint mir ein Problem in der Shell zu sein. Ersetzen Sie das ;durch ein newlineund es funktioniert. Otoh, lass die Zeile mit weg continueund du bekommst den Fehler. Lies die Quelle, Ben.
ott--

Antworten:

14

Denn es thenist weder ein Befehl noch eine Shell eingebaut, sondern eigentlich ein Teil der ifSyntax. Von 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.

Also das:

if [ $table = "Session" ]; then continue; fi

funktioniert, weil beide [ $table = "Session" ]und continueBefehle sind, die alleine stehen können; Sie bilden den jeweiligen listTeil des ifBefehls. Fügen Sie diese einfach in eine interaktive Shell ein und Sie werden sehen, dass sie keine Syntaxfehler verursachen:

martin@martin:~$ export table=test
martin@martin:~$ [ $table = "Session" ]
martin@martin:~$ continue
bash: continue: only meaningful in a `for', `while', or `until' loop

Auf der anderen Seite thenist es kein wirklicher Befehl, der für sich allein stehen kann:

martin@martin:~$ then
bash: syntax error near unexpected token `then'

In den ersten beiden Beispielen verwenden Sie also ifgenau so, wie es in der Manpage beschrieben wird:

if list; then list; fi

Wenn Sie jedoch einen ;Rückstand setzen then, bashwird dies als Syntaxfehler angezeigt. Zugegeben, die Shell-Syntax kann manchmal ziemlich verwirrend erscheinen, besonders wenn Sie gerade erst damit anfangen. Ich erinnere mich, dass ich sehr verwirrt darüber war, dass Leerzeichen erforderlich sind, [und ]sobald Sie feststellen, dass [es sich tatsächlich um einen Befehl oder eine eingebaute Shell handelt, ist dies verständlich. :) :)

Martin von Wittich
quelle
7

Sie müssen nach einem Befehl ein Semikolon einfügen. [ … ]ist ein Befehl, wie er ist continue. Auf der anderen Seite, if, thenund fisind keine Befehle: sie reservierte Worte sind.

ifsieht aus wie ein Befehl, aber das liegt daran, dass fast immer genau ein Befehl folgt. Es ist gültig zu schreiben

if print_table_value >foo; [ "$(cat foo)" = "Session" ]; then 

die auch auf verschiedene Arten dargestellt werden kann, wie z

if
  print_table_value >foo
  [ "$(cat foo)" = "Session" ]
then

Die allgemeine Syntax eines bedingten Befehls lautet

wenn zusammengesetzte Liste dann zusammengesetzte Liste 
(elif zusammengesetzte Liste dann zusammengesetzte Liste ) * 
(sonst zusammengesetzte Liste dann zusammengesetzte Liste ) ?
fi

wo

  • Die Zeilenumbrüche dienen nur der Lesbarkeit.
  • Eine zusammengesetzte Liste ist eine Liste von Befehlen, die jeweils durch eine ;oder eine neue Zeile abgeschlossen werden.
  • (…) ? zeigt ein optionales Teil an und (…) * zeigt ein Teil an, das 0, 1 oder viele Male wiederholt werden kann.

Schlüsselwörter werden nur am Anfang eines Befehls als solche erkannt.

Ein bedingter Befehl muss mit dem Schlüsselwort enden fi. Dies beseitigt nicht die Notwendigkeit, von einem Bediener befolgt zu werden, wenn ein anderer Befehl danach angezeigt wird. Wenn auf die Bedingung beispielsweise ein anderer Befehl folgen soll, muss ;dazwischen eine oder eine neue Zeile stehen. Wenn die Bedingung im Hintergrund ausgeführt werden soll, muss sie gefolgt werden &usw.

Gilles 'SO - hör auf böse zu sein'
quelle