Errore di sintassi Bash: fine del file imprevisto


98

Perdonami per questo è uno script molto semplice in Bash. Ecco il codice:

#!/bin/bash
# june 2011

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

dopo aver eseguito sh file.sh:

errore di sintassi: fine del file imprevisto

Risposte:


137

Penso che file.sh sia con terminatori di riga CRLF.

correre

dos2unix file.sh

allora il problema sarà risolto.

Puoi installare dos2unix in Ubuntu con questo:

sudo apt-get install dos2unix

Qual è la ragione di questo problema? Di solito lavoro su Windows ma ho bisogno di trasferire script su sistemi Unix.
CMCDragonkai

La nuova riga in Windows è "\ r \ n", mentre in Linux è "\ n".
Clyfish

8
@KeesdeKooter Non direi solo perché qualcosa non ha funzionato per te che dovresti votarlo verso il basso, chiaramente ha funzionato per i 28 voti positivi. Un semplice che non ha funzionato per me è sufficiente. Ecco perché SO ha consentito più risposte a una domanda perché possono esserci più soluzioni a un problema.
Jeff Wilbert,

2
L'utilizzo dell'editor di notepad ++ Modifica> Conversione EOL> Vecchio formato Mac lo ha risolto per me.
raktale

Se puoi modificare il tuo file bash con Notepad ++. Vai a Modifica-> Conversione EOL-> Macintosh (CR). Modificare in Macintosh (CR) anche se si utilizza il sistema operativo Windows.
Juniar

127

Un'altra cosa da controllare (mi è appena accaduta):

  • terminare i corpi delle funzioni a riga singola con punto e virgola

Cioè questo snippet dall'aspetto innocente causerà lo stesso errore:

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

Per rendere felice lo stupido parser:

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

3
+1 Si applica anche agli snippet di codice tra parentesi in questo modo: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n "" blah "|| {printf "% s \ n" "blahblah"; utilizzo; } ............ Notare che il punto e virgola all'interno delle parentesi graffe, subito dopo aver chiamato "utilizzo" una funzione definita in precedenza. Dimenticarlo ti darà lo stesso errore di sintassi: eof inaspettato.
Cbhihe

l'hai inchiodato. In realtà la cosa semplice ;è che ci si aspetta che l'istruzione Every finisca con in ;modo che alla fine es: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fiprodurrà quell'errore, mentre if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;non ... noterà i piccoli punti e virgola alla fine, cioè: dopo .bashe fi.
Emmanuel Mahuni

1
Avevo questo in uno script condiviso con me da un zshutente. Il primo funziona zshma non in shnor bash. Vorrei essere in 4 persone in modo da poter dare questi 4 voti positivi
Davos

41

Inoltre ho appena ricevuto questo messaggio di errore utilizzando la sintassi sbagliata in una ifclausola

  • else if (errore di sintassi: fine del file imprevisto)
  • elif (sintassi corretta)

ho eseguito il debug commentando i bit fino a quando non ha funzionato


Grazie mille .. qualcuno, per favore, dia a questo ragazzo una medaglia
Happiehappie il

16

una clausola if => fi non chiusa solleverà anche questo

suggerimento: usa trap per eseguire il debug, se il tuo script è enorme ...

per esempio

set -x
trap read debug

1
Ho esattamente dimenticato il "fi"! Grazie :) Se potessi, a beneficio di tutti, elaborare un po 'sulla tua punta di usare trap.
Carles Alcolea

3
scusa per il ritardo, amico mio. 'il comando' trap 'è un modo per eseguire il debug degli script interrompendo essenzialmente dopo ogni riga. una discussione più completa è qui: stackoverflow.com/questions/9080431/...
theRiley

1
È stato utile, grazie mille. Notare che l' unexpected end of fileerrore si verificherà non appena fiviene colpito.
Stephane B.

8

Ho ottenuto questa risposta da questo problema simile su StackOverflow

Apri il file in Vim e prova

:set fileformat=unix

Converti le terminazioni di linea eh in terminazioni unix e vedi se questo risolve il problema. Se si modifica in Vim, immettere il comando: set fileformat = unix e salvare il file. Molti altri editor hanno la capacità di convertire le terminazioni di riga, come Notepad ++ o Atom

Grazie @lemongrassnginger


Questi sono solo modi alternativi per fare dos2unixcome suggerisce la risposta accettata.
ulidtko

7

su cygwin avevo bisogno di: -

 export SHELLOPTS
 set -o igncr

in .bash_profile. In questo modo non avevo bisogno di eseguire unix2dos


6

Quindi ho trovato questo post e le risposte non mi hanno aiutato, ma sono stato in grado di capire perché mi ha dato l'errore. Ho avuto una

cat > temp.txt < EOF
some content
EOF

Il problema era che ho copiato il codice sopra per essere in una funzione e ho inavvertitamente tabulato il codice. È necessario assicurarsi che l'ultimo EOF non sia tabulato.


1
Questo era esattamente il mio caso. Avevo EOFrientrato di quattro spazi e bash non l'ha analizzato per questo motivo. La rimozione degli spazi ha risolto il problema.
aexl

5

Ho avuto il problema quando ho scritto l'istruzione "if - fi" in una riga:

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

Scrivi multilinea ha risolto il mio problema:

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

3

Questo stava accadendo per me quando stavo cercando di chiamare una funzione utilizzando parentesi, ad es

run() {
  echo hello
}

run()

dovrebbe essere:

run() {
  echo hello
}

run

2

PER FINESTRE:

Nel mio caso, stavo lavorando su un sistema operativo Windows e ho ricevuto lo stesso errore durante l'esecuzione di autoconf.

  • Ho semplicemente aperto il file configure.ac con il mio IDE NOTEPAD ++ .
  • Quindi ho convertito il file con conversione EOL in Windows (CR LF) come segue:

    MODIFICA -> CONVERSIONE EOL -> WINDOWS (CR LF)


1

Sono riuscito a tagliare e incollare il tuo codice in un file e ha funzionato correttamente. Se lo esegui in questo modo dovrebbe funzionare:

Il tuo "file.sh":

#!/bin/bash
# june 2011

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

Il comando:

$ ./file.sh arg1 arg2 arg3

Nota che "file.sh" deve essere eseguibile:

$ chmod +x file.sh

Potresti ricevere quell'errore b / c su come stai facendo l'input (con una pipa, una carota, ecc.). Puoi anche provare a dividere la condizione in due:

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

Oppure, poiché stai utilizzando bash, potresti utilizzare la sintassi incorporata:

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

E, infine, puoi ovviamente controllare se sono stati forniti 3 argomenti (pulito, mantiene la compatibilità della shell POSIX):

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

ho ancora lo stesso errore. Non sono esattamente sicuro di dove il codice vada storto
markcruz

strano, ho tagliato e incollato il tuo codice e ha funzionato come previsto. ci sono stati altri errori in uscita? molto tempo bash elencherà un numero di riga. inoltre, quale sistema stai utilizzando? (Linux, MacOS, BSD, distro, ecc.)
aaronstacy

0

Ho appena tagliato e incollato il tuo esempio in un file; ha funzionato bene sotto bash. Non vedo alcun problema con esso.

Per buona misura potresti assicurarti che finisca con una nuova riga, anche se a bash non dovrebbe importare. (Funziona sia con che senza il ritorno a capo finale.)

A volte vedrai strani errori se hai accidentalmente incorporato un carattere di controllo nel file. Poiché è uno script breve, prova a creare un nuovo script incollandolo dalla tua domanda qui su StackOverflow o semplicemente riscrivendolo.

Quale versione di bash stai usando? ( bash --version)

In bocca al lupo!


0

Assicurati che il nome della directory in cui è presente il file .sh non abbia uno spazio. es: dì che se si trova in una cartella chiamata "Nuova cartella", ti imbatterai sicuramente nell'errore che hai citato. Invece chiamalo semplicemente "New_Folder". Spero che aiuti.


0

Apparentemente, alcune versioni della shell possono anche emettere questo messaggio quando l'ultima riga dello script manca di una nuova riga.


0

In Ubuntu:

$ gedit ~/.profile

Quindi File -> Save ase impostare end linesuUnix/Linux



0

Per le persone che utilizzano MacOS:

Se hai ricevuto un file con formato Windows e desideri eseguirlo su MacOS e visualizzi questo errore, esegui questi comandi.

brew install dos2unix
sh <file.sh>

0

La mancanza di una parentesi graffa di chiusura nella definizione di una funzione causerà questo errore come ho appena scoperto.

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

Che ovviamente dovrebbe essere così ...

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

0

Nel mio caso, c'è una ridondanza \in quanto segue:

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
}

C'è NON una \alla fine delDATA.PATH_PREFIX ./afs/kinetics400

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.