Error de sintaxis bash: final inesperado del archivo


98

Perdóname por esto, es un script muy simple en Bash. Aquí está el código:

#!/bin/bash
# june 2011

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

después de ejecutar sh file.sh:

error de sintaxis: final inesperado del archivo

Respuestas:


137

Creo que file.sh está con terminadores de línea CRLF.

correr

dos2unix file.sh

entonces el problema se solucionará.

Puede instalar dos2unix en ubuntu con esto:

sudo apt-get install dos2unix

¿Cuál es la razón detrás de este problema? Normalmente trabajo en Windows, pero necesito transferir scripts a sistemas Unix.
CMCDragonkai

La nueva línea en Windows es "\ r \ n", mientras que en Linux es "\ n".
Clyfish

8
@KeesdeKooter Yo no diría que solo porque algo no funcionó para usted debería rechazarlo, claramente funcionó para los 28 votos a favor. Un simple que no funcionó para mí es suficiente. Es por eso que SO permitió múltiples respuestas a una pregunta porque puede haber múltiples soluciones a un problema.
Jeff Wilbert

2
Usar el editor de notepad ++ Editar> Conversión EOL> Formato Mac antiguo lo resolvió por mí.
raktale

Si puede editar su archivo bash con Notepad ++. Vaya a Editar-> Conversión EOL-> Macintosh (CR). Cámbielo a Macintosh (CR) incluso si está utilizando el sistema operativo Windows.
Juniar

126

Otra cosa para verificar (se me acaba de ocurrir):

  • terminar cuerpos de funciones de una sola línea con punto y coma

Es decir, este fragmento de aspecto inocente provocará el mismo error:

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

Para hacer feliz al analizador tonto:

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

3
+1 También se aplica a fragmentos de código con corchetes como este: [["$ #" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "% s \ n "" bla "|| {printf "% s \ n" "blahblah"; uso; } ............ Tenga en cuenta que el punto y coma dentro de los corchetes serpenteantes, justo después de llamar a alguna función previamente definida 'uso'. Si lo olvida, obtendrá el mismo error de sintaxis: eof inesperado.
Cbhihe

lo lograste. En realidad, lo simple es ;que se espera que la instrucción Every termine con, ;por lo que al final, por ejemplo: if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fiproducirá ese error, mientras if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;que no ... notará los pequeños puntos y coma al final, es decir, después de .bashy fi.
Emmanuel Mahuni

1
Tenía esto en un script compartido conmigo por un zshusuario. El primero funciona en zshpero no en shni bash. Ojalá fuera 4 personas para poder dar estos 4 votos a favor
Davos

40

También acabo de recibir este mensaje de error al usar la sintaxis incorrecta en una ifcláusula

  • else if (error de sintaxis: final inesperado del archivo)
  • elif (sintaxis correcta)

lo depuré comentando bits hasta que funcionó


Muchas gracias ... alguien, por favor, déle una medalla a este chico
Happiehappie

16

una cláusula if => fi no cerrada también aumentará esto

consejo: use trap para depurar, si su script es enorme ...

p.ej

set -x
trap read debug

1
¡Me olvidé exactamente del "fi"! Gracias :) Si pudiera, en beneficio de todos, elabore un poco su consejo sobre el uso de trampa.
Carles Alcolea

3
perdón por la demora, amigo. 'el comando' trap 'es una forma de depurar sus scripts rompiendo esencialmente después de cada línea. una discusión más completa está aquí: stackoverflow.com/questions/9080431/…
theRiley

1
Eso fue útil muchas gracias. Tenga en cuenta que el unexpected end of fileerror se producirá tan pronto como fise golpee.
Stephane B.

8

Obtuve esta respuesta de este problema similar en StackOverflow

Abra el archivo en Vim e intente

:set fileformat=unix

Convierta los finales de línea eh a finales de Unix y vea si eso resuelve el problema. Si edita en Vim, ingrese el comando: set fileformat = unix y guarde el archivo. Varios otros editores tienen la capacidad de convertir finales de línea, como Notepad ++ o Atom

Gracias @lemongrassnginger


Estas son solo formas alternativas de hacer lo dos2unixque aconseja la respuesta aceptada.
ulidtko

7

en cygwin necesitaba: -

 export SHELLOPTS
 set -o igncr

en .bash_profile. De esta manera no necesitaba ejecutar unix2dos


6

Así que encontré esta publicación y las respuestas no me ayudaron, pero pude averiguar por qué me dio el error. Tuve un

cat > temp.txt < EOF
some content
EOF

El problema fue que copié el código anterior para que estuviera en una función y, sin darme cuenta, puse el código en una pestaña. Necesito asegurarse de que el último EOF no esté marcado con pestañas.


1
Este fue exactamente mi caso. Había EOFsangrado cuatro espacios y bash no lo analizó por eso. Eliminar espacios solucionó el problema.
aexl

5

Tuve el problema cuando escribí la declaración "if - fi" en una línea:

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

Escribir multilínea resolvió mi problema:

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

3

Esto me estaba sucediendo cuando intentaba llamar a una función usando parens, por ejemplo

run() {
  echo hello
}

run()

debiera ser:

run() {
  echo hello
}

run

2

PARA VENTANAS:

En mi caso, estaba trabajando en el sistema operativo Windows y recibí el mismo error mientras ejecutaba autoconf.

  • Simplemente abro el archivo configure.ac con mi IDE NOTEPAD ++ .
  • Luego convertí el archivo con conversión EOL a Windows (CR LF) de la siguiente manera:

    EDITAR -> CONVERSIÓN EOL -> WINDOWS (CR LF)


1

Pude cortar y pegar su código en un archivo y se ejecutó correctamente. Si lo ejecuta así, debería funcionar:

Su "file.sh":

#!/bin/bash
# june 2011

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

El comando:

$ ./file.sh arg1 arg2 arg3

Tenga en cuenta que "file.sh" debe ser ejecutable:

$ chmod +x file.sh

Es posible que obtenga ese error b / c de cómo está haciendo la entrada (con una tubería, zanahoria, etc.). También puede intentar dividir la condición en dos:

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

O, ya que está usando bash, puede usar la sintaxis incorporada:

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

Y, finalmente, por supuesto, puede verificar si se dieron 3 argumentos (limpio, mantiene la compatibilidad con el shell POSIX):

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

sigo teniendo el mismo error. No estoy exactamente seguro de dónde va mal el código
markcruz

extraño, corté y pegué su código y funcionó como se esperaba. ¿Hubo más salida de error? mucho tiempo bash mostrará un número de línea. además, ¿qué sistema está ejecutando? (Linux, MacOS, BSD, distribución, etc.)
aaronstacy

0

Acabo de cortar y pegar su ejemplo en un archivo; funcionó bien bajo bash. No veo ningún problema con eso.

En buena medida, es posible que desee asegurarse de que termine con una nueva línea, aunque a bash no debería importarle. (Se ejecuta para mí con y sin la nueva línea final).

A veces, verá errores extraños si ha incrustado accidentalmente un carácter de control en el archivo. Dado que es un script corto, intente crear un nuevo script pegándolo de su pregunta aquí en StackOverflow, o simplemente volviendo a escribirlo.

¿Qué versión de bash estás usando? ( bash --version)

¡Buena suerte!


0

Asegúrese de que el nombre del directorio en el que está presente el archivo .sh no tenga un carácter de espacio. Por ejemplo: digamos que si está en una carpeta llamada 'Nueva carpeta', seguramente encontrará el error que ha citado. En su lugar, simplemente nómbrelo como 'New_Folder'. Espero que esto ayude.


0

Aparentemente, algunas versiones del shell también pueden emitir este mensaje cuando la última línea de su script carece de una nueva línea.


0

En Ubuntu:

$ gedit ~/.profile

A continuación, File -> Save asy establecer end lineaUnix/Linux



0

Para personas que usan MacOS:

Si recibió un archivo con formato de Windows y deseaba ejecutarlo en MacOS y ve este error, ejecute estos comandos.

brew install dos2unix
sh <file.sh>

0

La falta de una llave de cierre en la definición de una función causará este error como acabo de descubrir.

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

Que por supuesto debería ser así ...

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

0

En mi caso, hay un redundante \de la siguiente manera:

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
}

Hay NO una \al final deDATA.PATH_PREFIX ./afs/kinetics400

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.