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

Markcruz
quelle

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
Clyfish
quelle
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; }
ulidtko
quelle
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

Marengaz
quelle
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
theRiley
quelle
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

Jay Killeen
quelle
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

zzapper
quelle
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.

Rafael Urena
quelle
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
Sergey
quelle
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
Christian Scott
quelle
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)

Juniar
quelle
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
aaronstacy
quelle
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!

Adam Liss
quelle
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.


quelle
0

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

Tripleee
quelle
0

In Ubuntu:

$ gedit ~/.profile

Dann File -> Save asund setzen end lineaufUnix/Linux

Neb
quelle
0

Ich weiß, ich bin zu spät zur Party. Hoffe das kann jemandem helfen.

Überprüfen Sie Ihre .bashrc-Datei. Vielleicht umbenennen oder verschieben.

Diskussion hier: Es kann kein einfaches Bash-Skript erstellt werden

viggy28
quelle
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>
vmorusu
quelle
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"
}
Mike
quelle
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

einer
quelle