Syntaxfehler in der Nähe des unerwarteten Tokens „fi“

Syntaxfehler in der Nähe des unerwarteten Tokens „fi“

Ich möchte nicht unbedingt die Antwort, aber wenn mir jemand Literatur oder Beispiele zeigen könnte, würde ich es gern herausfinden.

Wenn ich das Skript ausführe, erhalte ich eine Fehlermeldung:

Syntaxfehler in der Nähe eines unerwarteten Tokensfi

Ich bin zu dem Schluss gekommen, dass mein Problem in meiner ifAussage liegt, indem ich meine ifAussagen mit Kommentaren versieht und hinzufüge, echo "$NAME"wodurch die Namen in angezeigt werden /etc/.

Wenn ich Änderungen vornehme, das „ #von“ ifund das „zu“ entferne und das „ zu“ fihinzufüge , erhalte ich den oben aufgeführten Syntaxfehler. Ich habe dann „dazwischen“ hinzugefügt . Ich bin auch ohne Lösung zur nächsten Zeile gegangen.#wc -c "$NAME";]then

#!/bin/bash
for NAME in /etc/*
do

     if [ -r "$NAME" -af "$NAME" ] then
          wc -c "$NAME"
     fi
done

Antwort1

Schlüsselwörter wie if, then, else, , fi, forusw. casemüssen an einer Stelle stehen, an der die Shell einen Befehlsnamen erwartet. Andernfalls werden sie als normale Wörter behandelt. Zum Beispiel:

echo if

druckt nur if, es startet keine bedingte Anweisung.

In der Zeile

if [ -r "$NAME" -af "$NAME" ] then

das Wort thenist ein Argument des Befehls [(über das es sich beschweren würde, wenn es jemals ausgeführt würde). Die Shell sucht weiter nach dem thenund findet ein fiin der Befehlsposition. Da es ein gibt, ifdas immer noch nach seinem sucht then, fiist das unerwartet, es liegt ein Syntaxfehler vor.

Sie müssen ein Befehlsabschlusszeichen davor setzen, thendamit es als Schlüsselwort erkannt wird. Das gebräuchlichste Befehlsabschlusszeichen ist ein Zeilenumbruch, aber vor thenwird häufig ein Semikolon verwendet (das genau die gleiche Bedeutung wie ein Zeilenumbruch hat).

if [ -r "$NAME" -af "$NAME" ]; then

oder

if [ -r "$NAME" -af "$NAME" ]
then

Sobald Sie das behoben haben, erhalten Sie einen weiteren Fehler vom Befehl, [weil er nicht versteht -af. Sie meinten vermutlich

if [ -r "$NAME" -a -f "$NAME" ]; then

Obwohl die Testbefehle wie Optionen aussehen, können Sie sie nicht auf diese Weise bündeln. Sie sind Operatoren des [Befehls und müssen jeweils ein separates Wort sein (wie do [und ]).

Übrigens, obwohl [ -r "$NAME" -a -f "$NAME" ]es funktioniert, empfehle ich, entweder

[ -r "$NAME" ] && [ -f "$NAME" ]

oder

[[ -r $NAME && -f $NAME ]]

Es ist am besten, [ … ]Bedingungen einfach zu halten, da der [Befehl Operatoren nicht leicht von Operanden unterscheiden kann. Wenn $NAMEes wie ein Operator aussieht und an einer Position erscheint, an der der Operator gültig ist, könnte es als Operator analysiert werden. Dies wird in den einfachen Fällen, die in dieser Antwort gezeigt werden, nicht passieren, aber komplexere Fälle können riskant sein. Wenn Sie dies mit separaten Aufrufen schreiben [und die logischen Operatoren der Shell verwenden, vermeiden Sie dieses Problem.

Die zweite Syntax verwendet die [[ … ]]bedingte Konstruktion, die in Bash (und Ksh und Zsh, aber nicht in einfachem Sh) vorhanden ist. Diese Konstruktion ist eine spezielle Syntax, die [wie jeder andere Befehl analysiert wird. Daher können Sie Dinge wie &&inside verwenden und müssen Variablen nicht in Anführungszeichen setzen, außer in Argumenten einiger String-Operatoren ( =, ==, !=, =~) (sieheWann sind doppelte Anführungszeichen erforderlich?für Details).

Antwort2

Hier erfahren Sie, was sich geändert hat

wenn [ -r "$NAME"-a -f"$NAME" ];Dann
# ^^^^^^ ^
     wc -c "$NAME"
fi

Wenn Sie alle Befehle im if-Block entfernen möchten, müssen Sie mindestens einen Doppelpunkt hinzufügen, wie

if [ -r "$NAME" -a -f "$NAME" ]; then
    :
fi

oder einzeilige Version

if [ -r "$NAME" -a -f "$NAME" ]; then :; fi

Antwort3

Andere haben bereits darauf hingewiesen, aber wenn Sie nach einer offiziellen Referenz suchen, dannRTM

wenn Liste; dann Liste; [ elif Liste; dann Liste; ] ... [ sonst Liste;] fi

Die if-Liste wird ausgeführt. Wenn ihr Beendigungsstatus Null ist, wird die then-Liste ausgeführt. Andernfalls wird jede elif-Liste nacheinander ausgeführt, und wenn ihr Beendigungsstatus Null ist, wird die entsprechende then-Liste ausgeführt und der Befehl abgeschlossen. Andernfalls wird die else-Liste ausgeführt, falls vorhanden. Der Beendigungsstatus ist der Beendigungsstatus des zuletzt ausgeführten Befehls oder Null, wenn keine Bedingung als erfüllt getestet wurde.

Sie vermissen die;

Und die Syntax fürlistwird beschrieben inman test

verwandte Informationen