unerwartetes EOF bei der Suche nach passendem `" '- Bash-Skript


37

Ich habe gerade ein Bash-Skript geschrieben und bekomme immer diesen EOF-Fehler.

Also hier ist mein Skript (funktioniert nur unter 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

Und hier ist mein Fehler:

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

Antworten:


31

Sie können Ihr Problem erkennen, wenn Sie sich nur Ihre Frage ansehen. Beachten Sie, wie die Syntaxhervorhebung nach Zeile 95 fehlerhaft ist:

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

Wie die Fehlermeldung besagt, haben Sie eine nicht übereinstimmende ". Entfernen Sie einfach das Extra "aus der obigen Zeile und es sollte Ihnen gut gehen:

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

1
Seltsamerweise hatte ich das gleiche Problem und es lag daran, dass ich eine sudo echo ""Zeile hatte. Durch Entfernen der 2 doppelten Anführungszeichen sudo echofunktioniert das perfekt.
Vinzee

@vinzee warum würden Sie jemals laufen echomit sudo? Das heißt, was Sie beschreiben, ergibt wenig Sinn, es muss etwas anderes passiert sein.
Terdon

Ich mache das, sudo echoweil das Skript sudospäter in den Befehlen benötigt wird, aber ich möchte, dass der Benutzer sein Passwort frühzeitig eingibt, damit das Skript einige Minuten lang keine Eingabe mehr benötigt. Und für den Fehler hatte ich den gleichen Fehler wie hier, aber er wurde durch Entfernen der 2 doppelten Anführungszeichen behoben. Nichts anderes ist passiert ..
Vinzee

1
@vinzee Vielleicht möchten Sie lesen Wie führe ich einen 'sudo'-Befehl in einem Skript aus? . Was die Zitate angeht, muss es noch etwas anderes gegeben haben. Möglicherweise hatten Sie nach den Anführungszeichen, die mit ihnen gelöscht wurden, ein nicht druckbares Zeichen. Oder vielleicht hatten Sie zwei einfache Anführungszeichen und dann ein double ( echo ''") oder so ähnlich, aber es musste etwas geben, da echo ""es in Ordnung ist.
Terdon

Danke für den Link, du hast recht. Das Laufen sudo echofühlte sich ein bisschen komisch an. Und ich werde es heute Abend noch einmal mit meiner Linux-Installation versuchen und zurückkommen, um hier die Ergebnisse zu kommentieren.
Vinzee

3

Dieser Fehler kann in realen Situationen schwer zu verfolgen sein. Hier biete ich eine Lösung für die reale Situation. Ich werde mein Skript als Beispiel verwenden.

Ich habe mein Shell-Skript aktualisiert. Beim Ausführen wurde folgende Fehlermeldung angezeigt:

/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

Dies ist die letzte Zeile mit doppelten Anführungszeichen.

Normalerweise überprüfe ich mein Shell-Skript jedes Mal, wenn ich es ändere. Diesmal habe ich einen Tag gewartet und vergessen, wo ich Änderungen vorgenommen hatte. Das Problem ist irgendwo vor dieser Zeile aufgetreten (1508). Das Problem ist, dass sogar ich Zeile 1508 auskommentiert habe

#elif [ "$project" ]; then

Der Shell-Henker sagte immer noch, Zeile 1508 habe Probleme.

Als nächstes habe ich eine Kopie des ursprünglichen Shell-Skripts erstellt. Löschen einer ganzen Reihe von Code von unten. Dann validieren Sie meinen Code mit dem folgenden Befehl

bash -n mysbashscript

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

Jetzt ist meine Datei 1/3 der Originalgröße. Ich sah sofort das Problem:

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

Aus irgendeinem Grund wird das nicht übereinstimmende "inside {}" nicht vom Shell-Parser erfasst. Hier kann der Shell-Parser weiter verbessert werden.

Der schnellste Algorithmus, um das Problem zu finden, besteht darin, die Hälfte Ihres Codes von unten zu löschen. Wenn der Syntaxfehler behoben ist, liegt er in dieser Hälfte. Wenn der Syntaxfehler immer noch da ist, liegt das Problem in der oberen Hälfte.

Wenn das Problem in der späteren Hälfte auftritt, machen Sie das Löschen rückgängig. Wiederholen Sie diesen Vorgang. Sie können auf eine kleinere Größe eingrenzen, um die Ursache des Problems zu ermitteln.

Wenn Sie Code löschen, müssen Sie einen ganzen Codeabschnitt löschen. Zum Beispiel die ganze Funktion.

Sie können entweder bash -n scriptname verwenden oder das Skript direkt ausführen. Beides sollte funktionieren.


1
„Aus irgendeinem Grund, die nicht ausgeglichene“ innerhalb {} von der Shell - Parser nicht erfasst wird.“Ist das nur syntaktisch , denn es wird abgestimmt, auf der Linie 1508? Dh die Zeichenfolge auf der Leitung geöffnet 500 auf der Leitung 1508 geschlossen ist, und dann ein anderer Die Saite wird am 1508 geöffnet und wird nie geschlossen.
Philh

Ich habe das Zitierverhalten von bash nicht untersucht. Bash hat möglicherweise ein mehrzeiliges Anführungszeichen "line1 \ nline2". Ich erinnere mich, dass Sie in der Shell ein mehrzeiliges Anführungszeichen mit << ENDMARK erstellen. Möglicherweise können Sie jetzt mehrere Zeilen direkt in Anführungszeichen setzen. Diese Funktion macht das Debuggen wirklich schwierig.
Kemin Zhou
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.