Le moyen le plus facile de find la citation manquante dans un bash un script?

J'ai un script bash qui est actuellement plus de 700 lignes. Après un cycle d'édition particulièrement long, il y a maintenant des erreurs comme ceci:

./run_me.sh: line 693: unexpected EOF while looking for matching `'' ./run_me.sh: line 702: syntax error: unexpected end of file 

Cependant, il n'y a rien de mal à voir à la ligne 693. Il n'y a même pas de citation à ce sujet.

J'ai essayé courir bash -x run_me.sh , et peut voir la dernière ligne, mais il n'y a rien de mal à cette ligne (et le code entre cette ligne et 693 est, en fait, la plupart du code).

Je peux commenter des parties entières du code, mais alors je suis plus susceptible de voir des erreurs dues aux fonctions manquantes, etc, plutôt que l'erreur EOF que je reçois.

Alors, comment quelqu'un est censé find la citation manquante, si le numéro de ligne est signalé incorrectement?

(Pourquoi le rapport de ligne de bash est-il si loin, de toute façon?)

modifier

Par ailleurs, je trouvais mon erreur particulière (en commentant swathes), qui était en fait manquante } dans une extension de variable à un numéro de ligne arbitraire nulle part près de la ligne indiquée par le message d'erreur. avec l'accolade manquante dans "${MY_ARRAY[@]" (devrait être "${MY_ARRAY[@]}" ).

Le moyen le plus facile? Utilisez un éditeur avec une coloration syntaxique qui est conscient du shell que vous utilisez, et inspectez visuellement. Lorsque vous obtenez une grosse nuance de couleur de string, vous savez que vous avez laissé un devis. À peu près n'importe quel éditeur de programmation décent a la coloration de la syntaxe.

La coloration de la syntaxe a parfois tort, mais c'est généralement un signe que votre programme est trop complexe et que les humains sont susceptibles de se tromper aussi.

Pour la programmation shell, assurez-vous d'utiliser une police où " , ' et ` sont faciles à distinguer. Vérifiez que vous n'avez pas utilisé par inadvertance des caractères non-ASCII qui ressemblent à des guillemets ASCII, tels que ''“” .

Un outil de peluchage externe comme ShellCheck peut détecter les problèmes et peut avoir de meilleurs messages et locations que se bash lui-même.

Pour un programme qui est principalement des déclarations d' echo avec un "${MY_ARRAY[1]" au milieu, ShellCheck vous indique qu'il n'a pas pu parsingr la string citée. Il épingle même le problème au caractère $ et indique que l'expansion du paramètre était en défaut.

ShellCheck fonctionne avec Vim, Emacs, SublimeText et Atom (entre autres).

Une approche low-tech est

 tr -cd "'\n" < run_me.sh | awk 'length%2==1 {print NR, $0}' 

Le tr supprime tous les caractères à l'exception des guillemets simples et des returns à la ligne, et le awk identifie les lignes qui ont un nombre impair de caractères (c.-à-d. Des guillemets qui ne correspondent pas). Vérifiez-les individuellement; Notez que les strings valides comme "That's not a bug!" sera marqué. Si cela ne met pas en évidence le problème, essayez de nouveau avec '"\n' (pour find des guillemets qui ne coïncident pas), puis développez le tr pour autoriser () , {} et finalement {} . point, l'inspection manuelle de la sortie devient une search less fructueuse, alors que ( et ) sont généralement appariés dans la même ligne, et les guillemets et les crochets sont presque toujours, ce n'est pas le cas de { et } .

Si vous avez réduit le problème à une incompatibilité de bouclage, et surtout si vous avez réduit une plage dans le file, allez à Plan B. Ouvrez le file dans vim (ou vi ). Accédez à un caractère { que vous croyez être avant l'erreur et tapez % . Si le slider saute à la } que vous pensez correspondre à la { vous avez commencé, avancez à la suivante { et répétez. S'il saute à un } qui ne correspond pas à { vous avez démarré, l'erreur se produit entre ces deux accolades. S'il ne bouge pas, l'erreur se produit entre votre position actuelle et la fin du file. Agrandir.

Cette approche peut être légèrement mieux adaptée aux files de programme dans des langages comme C, C ++ et Java (si leurs compilateurs ne font pas un travail suffisant), mais cela devrait fonctionner plutôt bien pour les scripts shell.

J'ai pu résoudre un gros problème que j'avais dans un script bash 2000+ lignes en utilisant la solution low-tech de G-Man.

Je voudrais juste append la ligne suivante qui fait la même chose pour le nombre impair de doublesquotes que la réponse de G-Man pour les guillemets simples.

 tr -cd "\"\n" < my_script.sh | awk 'length%2==1 {print NR, $0}' 

Btw, shellcheck.net est très sympa et tout bon script devrait passer par là.