Keine Werbung mögen? Gehen Werbefrei Heute

CRLF vs LF Der Zeilendurchbruch-Fehler, der CI unterbricht

Veröffentlicht am

Ihr Shell-Skript funktioniert lokal, aber bei CI mit einem rätselhaften Fehler des Interpreters. Die Ursache liegt meist in CRLF-Zeilenendungen. Erfahren Sie, was sie sind, warum sie Linux-Pipelines stören und wie Sie das Problem dauerhaft mit .gitattributes und Editor-Einstellungen beheben können.

CRLF vs LF: Der Zeilendurchbruch-Fehler, der CI unterbricht 1
ANZEIGE Entfernen?

Ihr Shell-Skript funktioniert auf Ihrem Laptop problemlos. Sobald Sie es auf GitHub pushen, wird es von CI abgerufen und die Pipeline sterbt mit einem rätselhaften Fehler – etwas wie /bin/bash^M: bad interpreter oder eine Aufgabe, die ohne offensichtigen Grund mit dem Rückgabewert 126 beendet wird. Das Skript ist syntaktisch korrekt. Sie haben keine Zeile geändert. Doch das Build ist kaputt.

Neun von zehn Mal ist der Schuldige eine Zeilendefinition. Genauer gesagt, Windows-artige CRLF-Zeilendefinitionen, die sich in einer Datei verstecken, die von Linux erwartet wird, nur LF zu finden. Dieser Artikel erklärt, was diese beiden Zeichen tatsächlich sind, warum der Unterschied wichtiger ist als die meisten Entwickler erkennen, und wie man das Problem dauerhaft beseitigt.

Was CRLF und LF tatsächlich bedeuten

Jeder Textdatei benötigt eine Art, um das Ende einer Zeile zu kennzeichnen. Zwei Steuerzeichen werden in verschiedenen Betriebssystemen verwendet:

  • LF (Zeilenabsatz, \n, Hexadezimal) 0x0A) – das Standardformat von Unix und Linux. macOS hat es seit OS X verwendet. Ein Byte pro Zeilendefinition.
  • CRLF (Tastenkraft + Zeilenabsatz, \r\n, Hexadezimal) 0x0D 0x0A) – das Windows-Standardformat, das von DOS erbt, das wiederum von Teletypmaschinen abgeleitet wurde. Zwei Bytes pro Zeilendefinition.

Die Namen stammen aus den physischen Aktionen eines alten Typenschiebers: Ein Zeilenrücklauf bewegte den Druckkopf zurück zum Anfang der Zeile; ein Zeilenabsatz rollte das Papier eine Zeile nach oben. DOS kodierte beide Aktionen literal. Unix nahm den minimalen Ansatz und behielt nur den Zeilenabsatz.

Warum CI bricht und Ihr Laptop nicht

Wenn Sie Code auf Windows schreiben und Ihr Editor Dateien mit CRLF speichert, funktioniert alles lokal – Windows-Tools behandeln beide Formate transparent. Doch Ihr CI-Pipeline läuft wahrscheinlich auf Linux, und Linux-Shell-Interpreter behandelt \r als einen druckbaren Zeichen, nicht als Leerzeichen. Wenn Bash eine Skriptzeile mit einem Ende in \r\nliest, sieht es das Befehlsskript plus einen trailing Carriage Return. Das Ergebnis sieht so aus:

/bin/bash^M: bad interpreter: No such file or directory

Der ^M in diesem Fehler ist, wie Terminals \rdarstellen. Bash versucht, eine Shebang-Zeile auszuführen, die mit einem Carriage Return endet, und natürlich existiert kein Interpreter an dieser Stelle.

Das gleiche Problem tritt in subtileren Formen auf:

  • Werte von Umgebungsvariablen mit trailing \r Zeichen, die String-Vergleiche schleichend brechen.
  • Docker ENTRYPOINT Skripte, die nicht starten, weil die Shebang korrupt ist.
  • Python-Skripte, die Konfigurationsdateien lesen und Schlüssel wie "setting\r" anstatt "setting".
  • bekommen. \r.

Makefiles, die Regeln ignorieren, weil der Tabzeichen durch

gefolgt wird.

Wie das Problem zu erkennen ist

cat -A deploy.sh

Bevor Sie etwas ändern, bestätigen Sie, dass die Datei tatsächlich CRLF-Zeilendefinitionen hat. Ein paar schnelle Methoden: ^M$ cat -A (Linux/macOS) $.

Zeilen, die mit CRLF enden, zeigen

file deploy.sh
# deploy.sh: Bash script, ASCII text, with CRLF line terminators

am Ende. Zeilen, die nur mit LF enden, zeigen nur

xxd deploy.sh | grep "0d 0a"

file command 0a xxd oder hexdump

Jede Übereinstimmung bestätigt CRLF. Wenn Sie nur

am Ende der Zeilen sehen, sind Sie sauber.

Wie das Problem zu beheben ist

# Install
sudo apt install dos2unix    # Debian/Ubuntu
brew install dos2unix        # macOS

# Convert a single file
dos2unix deploy.sh

# Convert all shell scripts in the repo
find . -name "*.sh" -exec dos2unix {} \;

dos2unix (die schnellste Lösung)

sed -i "s/\r//" deploy.sh

Installieren Sie es einmal, und führen Sie es auf jede Datei aus:

tr -d "\r" < deploy.sh > deploy_fixed.sh && mv deploy_fixed.sh deploy.sh

sed (keine zusätzlichen Tools erforderlich)

tr (POSIX-sicher)

Wie das Problem zu verhindern: Git-Konfiguration

A .gitattributes Die Behebung von Dateien nachträglich ist reaktiv. Die dauerhafte Lösung besteht darin, Git zu sagen, wie es Zeilendefinitionen behandelt, damit das Problem nie in Ihr Repository gelangt.

# Normalize all text files to LF in the repo
* text=auto eol=lf

# Explicitly enforce LF for files that must never have CRLF
*.sh text eol=lf
*.bash text eol=lf
Makefile text eol=lf
Dockerfile text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.json text eol=lf

# Binary files — do not touch
*.png binary
*.jpg binary
*.gif binary
*.zip binary
*.gz binary

Der text=auto eol=lf Der Ansatz mit .gitattributes (empfohlen)

Dateien, die in das Repository eingefügt werden, erzwingen konsistente Zeilendefinitionen für alle, unabhängig von ihren lokalen Git-Einstellungen. Fügen Sie dies an die Wurzel Ihres Repositories hinzu: .gitattributesline weist Git an, Textdateien automatisch zu erkennen und sie mit LF zu speichern, unabhängig von der Betriebssysteme der Entwickler. Die expliziten Zeilen darunter sperren Dateien ein, bei denen CRLF zu Laufzeitfehlern führen würde.

git add --renormalize .
git commit -m "normalize line endings"

Nachdem Sie

hinzugefügt oder geändert haben, core.autocrlf normalisieren Sie bestehende Dateien im Repository:

# Windows — convert CRLF to LF on commit, LF to CRLF on checkout
git config --global core.autocrlf true

# Linux/macOS — convert CRLF to LF on commit, no conversion on checkout
git config --global core.autocrlf input

Das Problem mit der Abhängigkeit von core.autocrlf allein: Es gilt nur auf dem Gerät, wo es eingestellt ist. Ein Beitrager, der es noch nie konfiguriert hat, kann weiterhin CRLF-Dateien pushen. Eine .gitattributes Datei wird durch das Repository selbst erzwungen, sodass sie streng可靠er ist.

Editor-Einstellungen, die richtig eingestellt werden müssen

Ihr Editor ist die erste Verteidigungslinie. Ein paar schnelle Einstellungen:

VS Code

Die Zeilendefinition für die aktuelle Datei wird in der Statusleiste (rechts unten) angezeigt. Klicken Sie darauf, um zwischen CRLF und LF umzuschalten. Um die Standardwerte für neue Dateien zu setzen, fügen Sie dies in Ihre settings.json:

{
  "files.eol": "\n"
}

JetBrains-IDEs (IntelliJ, WebStorm, PyCharm)

gehen Sie zu Einstellungen → Editor → Code-Stil und setzen Sie Zeilenseparator Zu Unix und macOS (\n). Sie können auch eine .editorconfig Datei an der Wurzel des Repositories hinzufügen:

[*]
end_of_line = lf
insert_final_newline = true

Die meisten modernen Editor respektieren .editorconfig nativ oder über einen Plugin. Wenn Sie es in das Repository einfügen, erhalten Benutzer konsistente Standardwerte ohne manuelle Konfiguration.

Die vollständige Checkliste

Wenn Sie ein Repository standardisieren, das bereits Zeilendefinitionsprobleme hatte, gehen Sie in dieser Reihenfolge vor:

  1. Fügen Sie eine .gitattributes Datei mit * text=auto eol=lf und explizite Regeln für Shell-Skripte, Dockerfiles und Konfigurationsdateien.
  2. Fügen Sie eine .editorconfig Datei mit end_of_line = lf.
  3. Führen Sie git add --renormalize . && git commit -m "normalize line endings" hinzu, um bestehende verfolgte Dateien zu korrigieren.
  4. Führen Sie dos2unix auf alle unverfolgten Skripte, die auf Linux ausgeführt werden.
  5. Set core.autocrlf input global auf Linux/macOS-Maschinen; true auf Windows.
  6. Fügen Sie einen CI-Prüfpass hinzu – etwas wie grep -rUl $'\r' *.sh – um jegliche Rückfälle vor der Bereitstellung zu erkennen.
Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

Die Anzeigetafel ist eingetroffen!

Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?