Shell-Skript funktioniert, wenn es mit Nano gespeichert wird, aber nicht, wenn es mit Notepad++ gespeichert wird

Shell-Skript funktioniert, wenn es mit Nano gespeichert wird, aber nicht, wenn es mit Notepad++ gespeichert wird

Wenn ich mein Bash-Skript aus Notepad++ in eine neue Datei mit dem Nano-Editor in SSH kopiere und speichere, läuft es einwandfrei. (sh ./install).

Aber wenn ich die Datei speichere (genau derselbe Inhalt), sie auf meinen Webserver hochlade und sie mit Wget auf derselben Maschine herunterlade, erhalte ich Syntaxfehler. Ich habe die Kodierung überprüft und sie scheint gleich zu sein. Seitdem habe ich eine Vielzahl von Zeichenkodierungen ausprobiert, um zu sehen, ob das Problem dadurch behoben wird. Ich mache die Datei auch ausführbar, sobald ich sie mit Wget herunterlade!

Die Datei läuft einwandfrei und ich habe keinerlei Fehler beim Kopieren und Einfügen mit Nano. Irgendeine Idee, woran das liegen könnte?

Antwort1

Ich würde wetten, dass das Problem mit den Zeilenenden zusammenhängt. Sie verwenden wahrscheinlich irgendwo auf der Strecke eine Nicht-*nix-Maschine. Ich hatte auch einmal ein Problem, bei dem apache(unter Linux) Zeilenenden im Windows-Stil zu hochgeladenen Textdateien hinzugefügt wurden, also sehen Sie möglicherweise etwas Ähnliches.

Zum Testen nehmen Sie die heruntergeladene Datei und führen Sie sie durch od. Wenn es sich um eine lange Datei handelt, nehmen Sie nur die ersten paar Zeilen:

head script.sh | od -c

Sehen Sie sich die Ausgabe an und prüfen Sie, ob sie etwa Folgendes enthält:

f   o   o  \r  \n

Dies \rist ein Wagenrücklauf und unter Windows werden Zeilen mit beendet, \r\nim Gegensatz zu \n*nix. Wenn sich herausstellt, dass dies tatsächlich das Problem war, können Sie Ihre Datei reparieren, indem Sie die Wagenrückläufe entfernen:

sed -i 's/\r//g' script.sh

Antwort2

@graeme hat scharfsinnig angemerkt, dass Sie, da Sie das Skript in beiden Formen auf dem Server haben, einen einfachen Test durchführen könnten, diffum zu ermitteln, was zwischen der funktionierenden Version und der problematischen Version unterschiedlich ist.

$ diff working.sh broken.sh

Sie können auch einen Side-by-Side-Diff wie folgt durchführen:

$ diff -y working.sh broken.sh

Wenn das Skript aufgrund eines Tippfehlers nicht funktioniert, können Sie dies häufig feststellen, indem Sie den -xSchalter zu hinzufügen bash, wodurch das Skript ausführlicher wird.

$ bash -x broken.sh

Sie können diesen Schalter auch #!/bin/bashwie folgt in den Shebang () oben in Ihren Skripten integrieren:

#!/bin/bash -x

Zeilenenden

Dies ist häufig das Problem beim Verschieben von Dateien von Windows auf Unix/Linux-Systeme. Das Problem hängt damit zusammen, wie die Zeilenenden auf den beiden Plattformen gekennzeichnet werden. Weitere Informationen hierzu finden Sie hier auf Wikipedia unter dem Titel:Zeilenumbrüche.

Erstellen Sie eine Beispieldatei

$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt

Wie @terdon in seiner Antwort beschrieben hat, können Sie seddiese entfernen. Sie können häufig auch ein Tool namens verwenden, dos2unixum dasselbe zu tun. Sie können es auf eine der beiden folgenden Arten verwenden:

$ dos2unix unixfile.txt

oder wenn Sie die vorhandene Datei nicht überschreiben möchten:

$ dos2unix -n oldfile.txt newfile.txt

Wenn Sie das oben genannte verwenden, differhalten Sie beim Vergleich dieser beiden Dateien eine Ausgabe wie diese:

$ diff -y unixfile.txt winfile.txt 
This is a couple                            |   This is a couple
of lines of sample                          |   of lines of sample
text.                                       |   text.

Sie werden die Unterschiede nicht erkennen können, nur dass sie da sind. Auch hier zeigt die Antwort von @terdon eine Methode, um das Problem mithilfe von zu lösen od. Sie können natürlich eine Vielzahl von Möglichkeiten nutzen, um herauszufinden, was los ist.

Verwenden von vim

mit dem filecmd.

$ file unixfile.txt
winfile.txt: ASCII text 

$ file winfile.txt 
unixfile.txt: ASCII text, with CRLF line terminators

Das Obige verdeutlicht das Problem, dass die Datei von Windows CRLF (Carriage Return + Linefeed-Zeichen am Ende der Zeilen) enthält. Diese Zeichen sind 0x0D und 0x0A in Hex, siehe auch dieWikipedia-Artikel über Zeilenumbrüchewenn Sie mehr darüber erfahren möchten.

Sie können vimdas Problem auch anzeigen, indem Sie Folgendes verwenden:

$ vim winfile.txt

Hier ist eine kleine Sequenz, die zeigt, was zu tun ist, vimum das Problem zu erkennen. Die CRLF-Zeichen werden unter Unix normalerweise als angezeigt ^M, also als Ctrl+ M.

                                       ss von vim

Die Sequenz zeigt, wie ich die Datei erneut öffne, winfile.txtals formatierte Unix-Datei ( :e ++ff=unix). Dies bedeutet, vimdass nicht automatisch erkannt werden soll, dass die Datei für Windows formatiert ist, und daher die ^MZeilenabschlusszeichen angezeigt werden.

verwandte Informationen