EOF inattendu lors de la recherche du `" 'correspondant - script bash

38

Je viens d'écrire un script bash et toujours obtenir cette erreur EOF.

Voici donc mon script (ne fonctionne que sur 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

Et voici mon erreur:

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

Réponses:

32

Vous pouvez voir votre problème si vous regardez simplement votre question. Notez comment la mise en évidence de la syntaxe est modifiée après la ligne 95:

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

Comme le message d'erreur vous le dit, vous avez une incomparable ". Supprimez simplement le surplus "de la ligne ci-dessus et ça devrait aller:

echo -e "Sorry, an error occurred. You have to run this on OS X"
terdon
la source
1
Étrangement, j'ai eu le même problème et c'était parce que j'avais une sudo echo ""ligne. Suppression des 2 guillemets doubles, ce qui sudo echopermet de le faire fonctionner parfaitement.
vinzee
@vinzee pourquoi voudriez-vous courir echoavec sudo? Cela dit, ce que vous décrivez n'a pas beaucoup de sens, il devait y avoir autre chose.
terdon
Je le fais sudo echoparce que le script aura besoin sudoultérieurement dans les commandes, mais je souhaite que l'utilisateur entre son mot de passe de bonne heure, afin que le script n'ait plus besoin de sa saisie pendant quelques minutes. Et pour le bogue, j'ai eu la même erreur que celle observée ici, mais elle a été résolue en supprimant les 2 guillemets doubles. Rien d'autre n'est arrivé ..
vinzee
1
@vinzee vous voudrez peut-être lire Comment exécuter une commande 'sudo' dans un script? . Quant aux citations, il devait y avoir autre chose. Vous avez peut-être par exemple un caractère non imprimable après les guillemets qui a été supprimé avec eux. Ou peut-être avez-vous eu deux guillemets simples, puis un double ( echo ''") ou quelque chose du genre, mais il devait bien y avoir quelque chose depuis echo "".
terdon
Merci pour le lien, vous avez raison. Courir sudo echome semblait un peu bizarre .. Et je vais réessayer sur mon installation linux ce soir et revenir pour commenter ici les résultats.
vinzee
4

Cette erreur peut être difficile à suivre dans des situations réelles. Ici, je propose une solution pour une situation réelle. Je vais utiliser mon script comme exemple.

J'ai mis à jour mon script shell. Lors de son exécution, j'ai reçu le message d'erreur suivant:

/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

Ceci est la dernière ligne qui a une paire de guillemets doubles.

Normalement, je vérifie mon script shell chaque fois que je le modifie. Cette fois-ci, j'ai attendu un jour et j'ai oublié où j'avais apporté des modifications. Le problème est arrivé n'importe où avant cette ligne (1508). Le problème est que même moi, j'ai commenté la ligne 1508

#elif [ "$project" ]; then

le bourreau a toujours dit que la ligne 1508 avait des problèmes.

Ensuite, j'ai fait une copie du script shell original. Supprimer tout un tas de code par le bas. Puis validez mon code avec la commande suivante

bash -n mysbashscript

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

Maintenant, mon fichier est 1/3 de la taille originale. J'ai tout de suite vu le problème:

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

Pour certaines raisons, l'analyseur de shell ne capture pas l'élément "inside {}" qui ne correspond à rien. C'est dans cette optique que l'analyseur de shell peut être encore amélioré.

L'algorithme le plus rapide pour trouver le problème consiste à supprimer la moitié de votre code par le bas. Si l'erreur de syntaxe disparaît, elle se trouve dans cette moitié. Si l'erreur de syntaxe est toujours présente, le problème se situe dans la moitié supérieure.

Si le problème survient dans la seconde moitié, annulez la suppression. Répétez ce processus. Vous pouvez réduire la taille du problème pour trouver la source.

Lorsque vous supprimez du code, vous devez supprimer toute une section de code. Par exemple toute la fonction.

Vous pouvez utiliser bash -n nom_script ou simplement exécuter directement le script. Les deux devraient fonctionner.

Kemin Zhou
la source
1
"Pour certaines raisons, l'analyseur de shell ne capture pas l'élément" inside {} "sans correspondance. Est-ce simplement parce que sa correspondance est syntaxique , sur la ligne 1508? chaîne est ouverte sur 1508 qui ne se ferme jamais
philh
Je n'ai pas enquêté sur le comportement des citations de bash. Bash peut avoir un devis multiligne "line1 \ nline2" Je me souviens que dans un shell, vous faites un devis multiligne avec << ENDMARK. Vous pouvez maintenant utiliser directement les guillemets doubles pour citer plusieurs lignes. Cette fonctionnalité rend le débogage très difficile.
Kemin Zhou