EOF inesperado mientras busca coincidencia '' '- script bash

38

Acabo de escribir un script bash y siempre obtengo este error EOF.

Así que aquí está mi script (solo funciona en OS X):

#!/bin/bash

#DEFINITIONS BEGIN
en_sq() {
    echo -e "Enabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart quotes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sq() {
    echo -e "Disabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart quotes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
en_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart dashes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart dashes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
#DEFINITIONS END
#---------------

#BEGIN OF CODE with properties
#This is only terminated if the user entered properties (eg ./sqd.sh 1 1)
if [ "$1" = "1" ]
    then
        en_sq
    elif [ "$1" = "0" ]
        then
            di_sq
fi

if [ "$2" = "1" ]
    then
        en_sd
        #exit 0 if both, $1 and $2 are correct entered and processed.
        exit 0
    elif [ "$1" = "0" ]
        then
            di_sd
            #exit 0 if both, $1 and $2 are correct entered and processed.
            exit 0
fi
#END OF CODE with properties
#---------------------------


#BEGIN OF CODE without properties
#This is terminated if the user didn't enter two properties
echo -e "\n\n\n\n\nINFO: You can use this command as following: $0 x y, while x and y can be either 0 for false or 1 for true."
echo -e "x is for the smart quotes, y for the smart dashes."
sleep 1
echo -e " \n Reading preferences...\n"
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart quotes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart quotes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X""
fi

status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart dashes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart dashes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X!"
fi

sleep 3
echo -e "\n\n You can now enable or disable smart quotes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sq" = "e" ]
    then
        en_sq
    elif [ "$sq" = "d" ]
        then
            di_sq
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done
SUCCESS="FALSE"

echo -e "\n\n You can now enable or disable smart dashes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sd" = "e" ]
    then
        en_sd
    elif [ "$sd" = "d" ]
        then
            di_sd
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done

Y aquí está mi error:

./coding.sh: line 144: unexpected EOF while looking for matching `"'
./coding.sh: line 147: syntax error: unexpected end of file
SimMac
fuente

Respuestas:

32

Puede ver su problema si solo mira su pregunta. Observe cómo el resaltado de sintaxis se arruina después de la línea 95:

echo -e "Sorry, an error occurred. You have to run this on OS X""

Como te dice el mensaje de error, tienes una incomparable ". Simplemente quite el extra "de la línea de arriba y debería estar bien:

echo -e "Sorry, an error occurred. You have to run this on OS X"
terdon
fuente
1
Curiosamente, tuve el mismo problema y fue porque tenía una sudo echo ""línea. Quitar las dos comillas dobles, dejarlo sudo echohace que funcione perfectamente.
vinzee
@vinzee ¿por qué alguna vez se queda echocon sudo? Dicho esto, lo que describe no tiene mucho sentido, debe haber sucedido algo más.
terdon
Lo hago sudo echoporque el script necesitará sudomás adelante en los comandos, pero quiero que el usuario ingrese su contraseña desde el principio, para que el script ya no necesite su entrada durante unos minutos. Y para el error, tuve el mismo error que se ve aquí, pero se resolvió eliminando las 2 comillas dobles. No pasó nada más ..
vinzee
1
@vinzee es posible que desee leer ¿Cómo ejecuto un comando 'sudo' dentro de un script? . En cuanto a las citas, debe haber habido algo más. Tal vez tenía un carácter que no se imprime después de las citas que se eliminaron con ellos, por ejemplo. O tal vez tenías dos comillas simples y luego un doble ( echo ''") o algo así, pero tenía que haber algo ya que echo ""está bien.
terdon
Gracias por el enlace, tienes razón. Correr se sudo echosintió un poco extraño. Y volveré a intentarlo en mi instalación de Linux esta noche y volveré a comentar aquí los resultados.
vinzee
4

Este error puede ser difícil de rastrear en situaciones reales. Aquí proporciono una solución para la situación del mundo real. Usaré mi script como ejemplo.

Actualicé mi script de shell. Al ejecutarlo recibí el siguiente mensaje de error:

/somepath/bin/myshellscript: line 1508: unexpected EOF while looking for matching `"'
/somepath/bin/myshellscript: line 1520: syntax error: unexpected end of file

line 1508 elif [ "$project" ]; then

Esta es la última línea que tiene un par de comillas dobles.

Normalmente, reviso mi script de shell cada vez que lo modifico. Esta vez, esperé un día y olvidé dónde había hecho modificaciones. El problema ocurrió en cualquier lugar antes de esta línea (1508). El problema es que incluso yo comenté la línea 1508

#elif [ "$project" ]; then

el verdugo de shell aún dijo que la línea 1508 tiene problemas.

Luego hice una copia del script de shell original. Eliminar un montón de código de la parte inferior. Luego validar mi código con el siguiente comando

bash -n mysbashscript

mybashscript: line 515: unexpected EOF while looking for matching `"'
mybashscript: line 561: syntax error: unexpected end of file

Ahora mi archivo es 1/3 del tamaño original. Inmediatamente vi el problema:

497 prepare_alignment() {
498     local projdir=${1:?"did not give project directory"}
499     local samp=${2:?"did not give sample name"}
500     local merged=${3:?"must give merged bam file name} # here is the problem

Por algún motivo, el analizador de shell no captura el "interior {} sin igual. Aquí es donde el analizador de shell puede mejorarse aún más.

El algoritmo más rápido para encontrar el problema es eliminar la mitad de su código desde la parte inferior, si el error de sintaxis desaparece, entonces está en esta mitad. Si el error de sintaxis sigue ahí, el problema está en la mitad superior.

Si hay problemas en la mitad posterior, deshaga la eliminación. Repite este proceso. Puede reducir a un tamaño más pequeño para encontrar la fuente del problema.

Al eliminar el código, debe eliminar una sección completa del código. Por ejemplo, toda la función.

Puede usar bash -n scriptname o simplemente ejecutar directamente el script. Ambos deberían funcionar.

Kemin Zhou
fuente
1
"Por alguna razón, el inigualable" dentro de {} no es capturado por el analizador cáscara ". ¿Es que sólo porque sintácticamente, que se corresponde, en la línea 1508? Es decir, la cadena abrió en la línea 500 se cierra en la línea 1508, y luego otra la cadena se abre en 1508 que nunca se cierra
philh
No investigué el comportamiento de citas de bash. Bash puede tener una cita de varias líneas "line1 \ nline2". Recuerdo que en la shell se hace una cita de varias líneas con << ENDMARK. Posiblemente ahora puede usar directamente comillas dobles para citar varias líneas. Esta característica hace que la depuración sea realmente difícil.
Kemin Zhou