Bash-Syntaxfehler: Unerwartetes Dateiende


97

Verzeih mir, dass dies ein sehr einfaches Skript in Bash ist. Hier ist der Code:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

nach dem Ausführen von sh file.sh:

Syntaxfehler: Unerwartetes Dateiende

Antworten:


137

Ich denke, file.sh ist mit CRLF-Zeilenabschlusszeichen.

Lauf

dos2unix file.sh

dann wird das Problem behoben.

Sie können dos2unix in Ubuntu folgendermaßen installieren:

sudo apt-get install dos2unix

Was ist der Grund für dieses Problem? Normalerweise arbeite ich unter Windows, muss aber Skripte auf Unix-Systeme übertragen.
CMCDragonkai

Newline in Windows ist "\ r \ n", während unter Linux "\ n" ist.
Clyfish

8
@KeesdeKooter Ich würde nicht sagen, nur weil etwas für dich nicht funktioniert hat, dass du es ablehnen solltest, klar, es hat für die 28 positiven Stimmen funktioniert. Ein einfaches, das bei mir nicht funktioniert hat, reicht aus. Aus diesem Grund hat SO mehrere Antworten auf eine Frage zugelassen, da es mehrere Lösungen für ein Problem geben kann.
Jeff Wilbert

2
Mit Notepad ++ Editor Bearbeiten> EOL-Konvertierung> Altes Mac-Format wurde es für mich gelöst.
Raktale

Wenn Sie Ihre Bash-Datei mit Notepad ++ bearbeiten können. Gehen Sie zu Bearbeiten-> EOL-Konvertierung-> Macintosh (CR). Ändern Sie es in Macintosh (CR), auch wenn Sie ein Windows-Betriebssystem verwenden.
Juniar

126

Eine andere Sache zu überprüfen (ist mir gerade eingefallen):

  • Beenden Sie Körper einzeiliger Funktionen mit einem Semikolon

Dh dieser unschuldig aussehende Ausschnitt verursacht den gleichen Fehler:

die () { test -n "$@" && echo "$@"; exit 1 }

Um den dummen Parser glücklich zu machen:

die () { test -n "$@" && echo "$@"; exit 1; }

3
+1 Gilt auch für Codefragmente mit Klammern wie folgt: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n "" bla "|| {printf "% s \ n" "blahblah"; Verwendung; } ............ Beachten Sie das Semikolon in den wellenförmigen Klammern, unmittelbar nachdem Sie eine zuvor definierte Funktion 'usage' aufgerufen haben. Wenn Sie dies vergessen, erhalten Sie denselben Syntaxfehler: Unerwartetes Eof.
Cbhihe

Du hast den Nagel auf den Kopf getroffen. Eigentlich ist die einfache Sache, ;dass erwartet wird, dass jede Aussage mit ;so endet , dass am Ende zB: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fidieser Fehler erzeugt wird, während if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;... die kleinen Semikolons am Ende nicht bemerkt werden, dh: nach .bashund fi.
Emmanuel Mahuni

1
Ich hatte dies in einem Skript, das mir von einem zshBenutzer mitgeteilt wurde. Ersteres funktioniert in, zshaber nicht in shnoch bash. Ich wünschte, ich wäre 4 Leute, damit ich diese 4 Upvotes geben könnte
Davos

39

Ich habe auch gerade diese Fehlermeldung erhalten, indem ich die falsche Syntax in einer ifKlausel verwendet habe

  • else if (Syntaxfehler: unerwartetes Dateiende)
  • elif (korrekte Syntax)

Ich debuggte es, indem ich Bits auskommentierte, bis es funktionierte


Vielen Dank. Jemand, bitte geben Sie diesem Kerl eine Medaille
Happiehappie

16

Eine nicht geschlossene if => fi-Klausel löst dies ebenfalls aus

Tipp: Verwenden Sie Trap zum Debuggen, wenn Ihr Skript sehr umfangreich ist ...

z.B

set -x
trap read debug

1
Ich habe das "fi" genau vergessen! Danke :) Wenn Sie zum Nutzen aller etwas über Ihren Tipp zur Verwendung von Trap sprechen könnten.
Carles Alcolea

3
Entschuldigung für die Verzögerung, mein Freund. Mit dem Befehl 'trap' können Sie Ihre Skripte debuggen, indem Sie nach jeder Zeile einen wesentlichen Fehler machen. Eine ausführlichere Diskussion finden Sie hier: stackoverflow.com/questions/9080431/…
theRiley

1
Das war nützlich, vielen Dank. Beachten Sie, dass der unexpected end of fileFehler auftritt, sobald der figetroffen wird.
Stephane B.

8

Ich habe diese Antwort von diesem ähnlichen Problem auf StackOverflow erhalten

Öffnen Sie die Datei in Vim und versuchen Sie es

:set fileformat=unix

Konvertieren Sie eh-Zeilenenden in Unix-Endungen und prüfen Sie, ob das Problem dadurch behoben wird. Geben Sie beim Bearbeiten in Vim den folgenden Befehl ein: set fileformat = unix und speichern Sie die Datei. Mehrere andere Editoren können Zeilenenden konvertieren, z. B. Notepad ++ oder Atom

Danke @lemongrassnginger


Dies sind nur alternative Möglichkeiten, dos2unixwie in der akzeptierten Antwort angegeben.
Ulidtko

7

auf cygwin brauchte ich: -

 export SHELLOPTS
 set -o igncr

in .bash_profile. Auf diese Weise musste ich unix2dos nicht ausführen


6

Also fand ich diesen Beitrag und die Antworten halfen mir nicht, aber ich konnte herausfinden, warum es mir den Fehler gab. Ich hatte ein

cat > temp.txt < EOF
some content
EOF

Das Problem war, dass ich den obigen Code kopiert habe, um in einer Funktion zu sein, und den Code versehentlich mit Registerkarten versehen habe. Stellen Sie sicher, dass der letzte EOF nicht mit Registerkarten versehen ist.


1
Das war genau mein Fall. Ich hatte EOFvier Leerzeichen eingerückt und Bash hat es deswegen nicht analysiert. Das Entfernen von Leerzeichen hat das Problem behoben.
Aexl

5

Ich hatte das Problem, als ich die Anweisung "if - fi" in eine Zeile schrieb:

if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi

Mehrzeiliges Schreiben löste mein Problem:

if [ -f ~/.git-completion.bash ]; then 
    . ~/.git-completion.bash
 fi

3

Dies geschah für mich, als ich versuchte, eine Funktion mit Parens aufzurufen, z

run() {
  echo hello
}

run()

sollte sein:

run() {
  echo hello
}

run

2

FÜR WINDOWS:

In meinem Fall habe ich unter Windows gearbeitet und beim Ausführen von autoconf den gleichen Fehler erhalten.

  • Ich öffne einfach die Datei configure.ac mit meiner NOTEPAD ++ IDE.
  • Dann habe ich die Datei mit EOL- Konvertierung in Windows (CR LF) wie folgt konvertiert :

    BEARBEITEN -> EOL-KONVERTIERUNG -> FENSTER (CR LF)


1

Ich konnte Ihren Code ausschneiden und in eine Datei einfügen, die ordnungsgemäß ausgeführt wurde. Wenn Sie es so ausführen, sollte es funktionieren:

Ihre "file.sh":

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Der Befehl:

$ ./file.sh arg1 arg2 arg3

Beachten Sie, dass "file.sh" ausführbar sein muss:

$ chmod +x file.sh

Möglicherweise erhalten Sie den Fehler b / c, wie Sie Eingaben machen (mit Pfeife, Karotte usw.). Sie können auch versuchen, die Bedingung in zwei Teile aufzuteilen:

if [ $# -lt 3 ] || [ $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Da Sie verwenden bash, können Sie auch die integrierte Syntax verwenden:

if [[ $# -lt 3 || $# -gt 3 ]]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Und schließlich können Sie natürlich auch überprüfen, ob 3 Argumente angegeben wurden (sauber, behält die POSIX-Shell-Kompatibilität bei):

if [ $# -ne 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

Ich habe immer noch den gleichen Fehler.
Ich bin

komisch, ich habe deinen Code ausgeschnitten und eingefügt und es hat wie erwartet funktioniert. Gab es noch mehr Fehler? Eine Menge Zeit wird eine Zeilennummer auflisten. Welches System verwenden Sie? (Linux, MacOS, BSD, Distribution usw.)
aaronstacy

0

Ich habe gerade Ihr Beispiel ausgeschnitten und in eine Datei eingefügt. es lief gut unter Bash. Ich sehe keine Probleme damit.

Für ein gutes Maß möchten Sie vielleicht sicherstellen, dass es mit einer neuen Zeile endet, obwohl Bash sich nicht darum kümmern sollte. (Es läuft für mich sowohl mit als auch ohne die letzte Zeile.)

Manchmal werden seltsame Fehler angezeigt, wenn Sie versehentlich ein Steuerzeichen in die Datei eingebettet haben. Da es sich um ein kurzes Skript handelt, versuchen Sie, ein neues Skript zu erstellen, indem Sie es aus Ihrer Frage hier in StackOverflow einfügen oder es einfach erneut eingeben.

Welche Version von Bash verwenden Sie? ( bash --version)

Viel Glück!


0

Stellen Sie sicher, dass der Name des Verzeichnisses, in dem sich die .sh-Datei befindet, kein Leerzeichen enthält. Beispiel: Wenn Sie sich in einem Ordner mit dem Namen "Neuer Ordner" befinden, werden Sie auf den von Ihnen genannten Fehler stoßen. Nennen Sie es stattdessen einfach "New_Folder". Ich hoffe das hilft.


0

Anscheinend können einige Versionen der Shell diese Nachricht auch ausgeben, wenn in der letzten Zeile Ihres Skripts keine neue Zeile vorhanden ist.


0

In Ubuntu:

$ gedit ~/.profile

Dann File -> Save asund setzen end lineaufUnix/Linux



0

Für Benutzer von MacOS:

Wenn Sie eine Datei im Windows-Format erhalten haben und unter MacOS ausgeführt werden möchten und dieser Fehler angezeigt wird, führen Sie diese Befehle aus.

brew install dos2unix
sh <file.sh>

0

Das Fehlen einer schließenden Klammer in einer Funktionsdefinition führt zu diesem Fehler, wie ich gerade entdeckt habe.

function whoIsAnIidiot() {
    echo "you are for forgetting the closing brace just below this line !"

Was natürlich so sein sollte ...

function whoIsAnIidiot() {
    echo "not you for sure"
}

0

In meinem Fall gibt es eine Redundanz \wie folgt:

function foo() {
    python tools/run_net.py \
                           --cfg configs/Kinetics/X3D_8x8_R50.yaml \
                           NUM_GPUS 1 \
                           TRAIN.BATCH_SIZE 8 \
                           SOLVER.BASE_LR 0.0125 \
                           DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
                           DATA.PATH_PREFIX  ./afs/kinetics400  \  # Error
}

Es ist NICHT ein \am EndeDATA.PATH_PREFIX ./afs/kinetics400

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.