Ich habe ein Bash-Skript, das derzeit mehr als 700 Zeilen lang ist. Nach einer besonders langen Bearbeitungsrunde gibt es nun folgende Fehler:
./run_me.sh: line 693: unexpected EOF while looking for matching `''
./run_me.sh: line 702: syntax error: unexpected end of file
Es gibt jedoch nichts Falsches, was ich an Zeile 693 sehen kann. Es gibt nicht einmal ein Zitat darauf.
Ich habe versucht zu laufen bash -x run_me.sh
und kann sehen, dass die letzte Zeile ausgeführt wird, aber auch an dieser Zeile ist nichts auszusetzen (und der Code zwischen dieser Zeile und 693 ist praktisch der größte Teil des Codes).
Ich kann ganze Teile des Codes auskommentieren, aber dann sehe ich eher Fehler aufgrund fehlender Funktionen usw. als den EOF-Fehler, den ich erhalte.
Wie soll jemand das fehlende Zitat finden, wenn die Zeilennummer falsch gemeldet wird?
(Warum ist die Zeilennummer von bash überhaupt so weit entfernt?)
Bearbeiten
Übrigens habe ich meinen speziellen Fehler gefunden (durch Kommentieren von Schwaden), der tatsächlich }
in einer variablen Erweiterung bei einer beliebigen Zeilennummer fehlte, die nicht in der Nähe der durch die Fehlermeldung angegebenen Zeile liegt - zitierbasierte Syntaxhervorhebung hat hier nicht geholfen, z die fehlende Klammer in "${MY_ARRAY[@]"
(sollte sein "${MY_ARRAY[@]}"
).
quelle
sh -nv <script
wie du. Sobald sich Ihre Fehlermeldung ändert, haben Sie den zusammengesetzten Befehl gefunden, in dem Ihr Problem liegt. Und die Zeilennummern sind in Ordnung - jede Funktion bekommt ihre eigene.-nv
Ding ausprobiert haben, bekommen Sie vielleicht eine bessere Idee - die Eingabeaufforderungen werden Sie darauf$PS2
hinweisen . Sie werden es bekommen, wenn die Shell irgendwann begonnen hat, ein Zitat oder eine zusammengesetzte Ebene zu interpretieren und es nicht geschafft hat Schließen Sie dieses Token, seit die letzte Zeile in der Eingabe aufgetreten ist. Versuchen Sie auch:PS4='LAST EXECLINE: $((LAST+!(LAST=LINENO)))'; set -x
weil die Leinen in Unterschalen manchmal ziemlich lustig werden können.Antworten:
Ein Low-Tech-Ansatz ist
Das
tr
löscht alle Zeichen mit Ausnahme von einfachen Anführungszeichen und Zeilenumbrüchen undawk
identifiziert die Zeilen mit einer ungeraden Anzahl von Zeichen (dh nicht übereinstimmenden Anführungszeichen). Überprüfen Sie sie einzeln; Beachten Sie, dass gültige Zeichenfolgen wie gekennzeichnet"That's not a bug!"
werden. Wenn das Problem dadurch nicht hervorgehoben wird, versuchen Sie es erneut mit'"\n'
(um nicht übereinstimmende doppelte Anführungszeichen zu finden). Als nächstes erweitert dastr
zu ermöglichen()
,{}
und schließlich{}
durch zu gehen. Zu diesem Zeitpunkt wird die manuelle Überprüfung der Ausgabe zu einer weniger fruchtbaren Angelegenheit. Während(
und)
normalerweise innerhalb derselben Zeile übereinstimmen und Anführungszeichen und eckige Klammern fast immer vorhanden sind, gilt dies nicht für{
und}
.Wenn Sie das Problem auf eine nicht übereinstimmende geschweifte Klammer eingegrenzt haben und insbesondere wenn Sie einen Bereich in der Datei eingegrenzt haben, fahren Sie mit Plan B fort. Öffnen Sie die Datei in
vim
(odervi
). Gehen Sie zu einem{
Zeichen, von dem Sie glauben, dass es vor dem Fehler steht, und geben Sie es ein%
. Wenn der Cursor zu dem springt, von dem}
Sie glauben, dass er mit dem übereinstimmt, mit dem{
Sie begonnen haben, fahren Sie mit dem nächsten fort{
und wiederholen Sie den Vorgang. Wenn zu einem}
Wert gesprungen wird, der nicht mit dem übereinstimmt, mit dem{
Sie begonnen haben, tritt der Fehler zwischen diesen beiden geschweiften Klammern auf. Wenn es nicht verschoben wird, tritt der Fehler zwischen Ihrem aktuellen Speicherort und dem Ende der Datei auf. Hineinzoomen.Dieser Ansatz eignet sich möglicherweise etwas besser für Programmdateien in Sprachen wie C, C ++ und Java (wenn ihre Compiler nicht gut genug arbeiten), sollte jedoch für Shell-Skripte recht gut funktionieren.
quelle
Einfachster Weg? Verwenden Sie einen Editor mit Syntaxfarbe, der die von Ihnen verwendete Shell kennt, und überprüfen Sie sie visuell. Wenn Sie einen großen Streifen String-Farbe erhalten, wissen Sie, dass Sie ein Zitat ausgelassen haben. Fast jeder anständige Programmiereditor hat Syntaxfarben.
Syntaxfärbung macht es manchmal falsch, aber das ist normalerweise ein Zeichen dafür, dass Ihr Programm zu komplex ist und Menschen es wahrscheinlich auch falsch machen.
Für Shell - Programmierung, stellen Sie sicher , eine Schriftart zu verwenden , wo
"
,'
und`
sind leicht auseinander zu halten . Stellen Sie sicher, dass Sie nicht versehentlich Nicht-ASCII-Zeichen verwendet haben, die wie ASCII-Anführungszeichen aussehen, z‘’“”
.quelle
}
Mangel in einer zitierten Zeichenfolge, die Geanys Kolorierung nicht entdeckte.vim
macht einen vernünftigen Job ... irgendwann. Zuerst mußte es nicht mehr ignorieren:syntax on
durch die Installationvim-enhanced
übervim-minimal
(dank Fedora!), Dann hatte sie in ein anständiges Farbschema zu zwingen, da dunkelblau war tatsächlich sichtbar (dank LXTerminal!). Danach,vim
tat Highlight Klammern mit einem schönen roten Hintergrund fehlt!Ein externes Flusen-Tool wie ShellCheck kann Probleme erkennen und hat möglicherweise bessere Nachrichten und Standorte als sich
bash
selbst.Bei einem Programm, bei dem es sich hauptsächlich um
echo
Anweisungen mit einem"${MY_ARRAY[1]"
in der Mitte handelt, weist ShellCheck darauf hin, dass die angegebene Zeichenfolge nicht analysiert werden konnte. Es führt das Problem sogar auf das$
Zeichen zurück und weist darauf hin, dass die Parametererweiterung fehlerhaft war.ShellCheck funktioniert unter anderem mit Vim, Emacs, SublimeText und Atom.
quelle
Mit der Low-Tech-Lösung von G-Man konnte ich ein großes Problem lösen, das ich in einem Bash-Skript mit mehr als 2000 Zeilen hatte.
Ich würde nur die folgende Zeile hinzufügen, die für eine ungerade Anzahl von Doppelzitaten dasselbe tut wie die Antwort von G-Man für Einzelzitate.
Übrigens ist shellcheck.net sehr nett und jedes gute Skript sollte es durchgehen.
quelle