Einige Compiler (insbesondere C- oder C ++ - Compiler) geben Warnungen zu folgenden Themen aus:
No new line at end of file
Ich dachte, dies wäre ein C-Programmierer-Problem, aber github zeigt eine Meldung in der Commit-Ansicht an:
\ No newline at end of file
für eine PHP-Datei.
Ich verstehe die in diesem Thread erläuterte Präprozessor-Sache , aber was hat das mit PHP zu tun? Ist es dasselbe include()
oder hat es etwas mit dem \r\n
vs- \n
Thema zu tun ?
Was bringt es, wenn am Ende einer Datei eine neue Zeile steht?
cat
die Datei haben, wird die nächste Eingabeaufforderung an die letzte "Zeile" angehängt, wenn sie nicht mit einer neuen Zeile endet.Antworten:
Es geht nicht darum, am Ende einer Datei einen zusätzlichen Zeilenumbruch einzufügen, sondern darum, den Zeilenumbruch, der vorhanden sein sollte, nicht zu entfernen.
Eine Textdatei unter Unix besteht aus einer Reihe von Zeilen , die jeweils mit einem Zeilenumbruchzeichen (
\n
) enden . Eine Datei, die nicht leer ist und nicht mit einem Zeilenumbruch endet, ist daher keine Textdatei.Dienstprogramme, die Textdateien verarbeiten sollen, kommen möglicherweise nicht mit Dateien zurecht, die nicht mit einem Zeilenumbruch enden. Beispielsweise können historische Unix-Dienstprogramme den Text nach dem letzten Zeilenumbruch ignorieren. GNU- Hilfsprogramme verhalten sich bei Nicht-Text-Dateien anständig, ebenso wie die meisten anderen modernen Hilfsprogramme. Es kann jedoch vorkommen, dass bei Dateien, denen eine letzte Zeile fehlt, ein ungewöhnliches Verhalten auftritt¹.
Wenn mit GNU diff eine der verglichenen Dateien mit einem Zeilenumbruch endet, die andere jedoch nicht, muss dies beachtet werden. Da diff zeilenorientiert ist, kann dies nicht durch Speichern einer neuen Zeile für eine der Dateien angezeigt werden, nicht jedoch für die anderen. Die neuen Zeilen sind erforderlich, um anzugeben, wo jede Zeile in der Diff-Datei beginnt und endet. Also verwendet diff diesen speziellen Text
\ No newline at end of file
, um eine Datei, die nicht mit einem Zeilenumbruch endet, von einer Datei zu unterscheiden, die dies tat.Übrigens besteht eine Quelldatei in einem C-Kontext in ähnlicher Weise aus einer Reihe von Zeilen. Genauer gesagt wird eine Übersetzungseinheit in einer Implementierung betrachtet, die als eine Reihe von Zeilen definiert ist, von denen jede mit einem Zeilenumbruchzeichen enden muss ( n1256 §5.1.1.1). Auf Unix-Systemen ist das Mapping einfach. Unter DOS und Windows wird jede CR LF-Sequenz (
\r\n
) einer neuen Zeile zugeordnet (\n
dies geschieht immer, wenn eine Datei gelesen wird, die unter diesen Betriebssystemen als Text geöffnet wurde). Es gibt einige Betriebssysteme, die kein Zeilenumbruchzeichen haben, sondern Datensätze mit fester oder variabler Größe. Auf diesen Systemen führt die Zuordnung von Dateien zu C-Quellen ein\n
am Ende jeder Aufzeichnung. Dies ist zwar für Unix nicht direkt relevant, bedeutet aber, dass Sie beim Kopieren einer C-Quelldatei, deren letzte Zeile fehlt, auf ein System mit datensatzbasierten Textdateien und beim anschließenden Zurückkopieren eine unvollständige Datei erhalten Letzte Zeile, die bei der anfänglichen Konvertierung abgeschnitten wurde, oder eine zusätzliche Zeile, die bei der umgekehrten Konvertierung angeheftet wurde.¹ Beispiel: Die Ausgabe von GNU sort endet immer mit einem Zeilenumbruch. Wenn der Datei
foo
die letzte Zeile fehlt, werden Sie feststellen, dass siesort foo | wc -c
ein Zeichen mehr als enthältcat foo | wc -c
.quelle
Nicht unbedingt der Grund, aber eine praktische Konsequenz von Dateien, die nicht mit einer neuen Zeile enden:
Überlegen Sie, was passieren würde, wenn Sie mehrere Dateien mit verarbeiten möchten
cat
. Wenn Sie beispielsweise das Wortfoo
am Zeilenanfang in drei Dateien suchen möchten:Beginnt die erste Zeile in Datei3 mit
foo
, aber Datei2 hat\n
nach der letzten Zeile kein Finale , würde dieses Vorkommen von grep nicht gefunden, da die letzte Zeile in Datei2 und die erste Zeile in Datei3 von grep als eine einzige Zeile angesehen würden Linie.Aus Gründen der Konsistenz und um Überraschungen zu vermeiden, versuche ich, meine Dateien immer mit einer neuen Zeile zu versehen.
quelle
'\n'
die Katzenoperation durchführen ...\n
oder ohne Leerzeichen an den Enden zusammen. Um die Dinge konsistent zu halten, setze ich immer\n _____
beide Enden meiner Strings an." Nun, nein, es ist das Richtige, wenn Sie Ihre Strings zuschneiden und dann richtig verketten.Es gibt zwei Aspekte:
Es gibt / gab einige C-Compiler, die die letzte Zeile nicht analysieren können, wenn sie nicht mit einer neuen Zeile endet. Der C-Standard legt fest, dass eine C-Datei mit einer neuen Zeile (C11, 5.1.1.2, 2.) enden soll und dass eine letzte Zeile ohne neue Zeile undefiniertes Verhalten ergibt (C11, J.2, 2. Punkt). Vielleicht aus historischen Gründen, weil ein Hersteller eines solchen Compilers bei der Erstellung des ersten Standards Teil des Komitees war. So die Warnung von GCC.
diff
Programme (wie sie vongit diff
, github usw. verwendet werden) zeigen zeilenweise Unterschiede zwischen Dateien an. Sie drucken normalerweise eine Nachricht, wenn nur eine Datei mit einem Zeilenumbruch endet, da Sie sonst diesen Unterschied nicht sehen würden. Zum Beispiel , wenn der einzige Unterschied zwischen zwei Dateien die Anwesenheit des letzten Newline - Zeichens ist, ohne den Hinweis darauf , wie die beiden Dateien waren die gleiche, wenn aussehen würdediff
undcmp
gibt einen austritt Code ungleich Erfolg und die Prüfsummen der Dateien (zB übermd5sum
) stimmen nicht überein.quelle
diff
Es wird erwartet, dass Differenzen gedruckt werden, wenn welche vorhanden sind. Und wenn eine Datei eine neue Zeile als letztes Zeichen hat, während die andere keine hat, muss dieser Unterschied in der Ausgabe irgendwie spürbar sein.\n
) anzeigen , sondern kann stattdessen einfach "new lines" anzeigen .Das, was
\ No newline at end of file
Sie von Github erhalten , wird am Ende eines Patches angezeigt (imdiff
Format siehe den Hinweis am Ende des Abschnitts "Einheitliches Format").Es ist den Compilern egal, ob sich am Ende einer Datei ein Zeilenumbruch befindet oder nicht, diese müssen jedoch
git
(und diediff
/patch
utilities) berücksichtigen. Dafür gibt es viele Gründe. Wenn Sie beispielsweise vergessen, eine neue Zeile am Ende einer Datei hinzuzufügen oder zu entfernen, ändert sich deren Hashsumme (md5sum
/sha1sum
). Dateien sind auch nicht immer Programme, und ein Final\n
kann einen Unterschied machen.Hinweis : Wegen der Warnung von C-Compilern bestehen sie vermutlich aus Gründen der Abwärtskompatibilität auf einer abschließenden neuen Zeile. Sehr alte Compiler akzeptieren möglicherweise nicht die letzte Zeile, wenn sie nicht mit
\n
(oder einer anderen systemabhängigen Zeichenfolge für das Zeilenende) enden.quelle
POSIX: Hierbei handelt es sich um eine Reihe von Standards, die von IEEE festgelegt wurden, um die Kompatibilität zwischen Betriebssystemen zu gewährleisten.
Eine davon ist die Definition einer "Zeile", die eine Folge von null oder mehr Nichtzeichen plus einem abschließenden Zeilenumbruchzeichen ist.
Damit diese letzte Zeile als tatsächliche "Zeile" erkannt wird, sollte sie ein abschließendes Zeichen für eine neue Zeile enthalten.
Dies ist wichtig, wenn Sie von OS-Tools abhängig sind, um die Zeilenanzahl zu bestimmen oder Ihre Datei zu teilen / zu analysieren. Angesichts der Tatsache, dass PHP eine Skriptsprache ist, ist dies durchaus möglich, insbesondere in den frühen Tagen oder sogar jetzt (ich habe keine Ahnung / Postulierung), da es solche Betriebssystemabhängigkeiten hatte.
In der Realität sind die meisten Betriebssysteme nicht vollständig POSIX-konform und der Mensch ist nicht so maschinenfreundlich oder kümmert sich auch nicht darum, neue Leitungen zu terminieren. Für die meisten Dinge ist es also ein Smorgasbord von allem, das sich entweder darum kümmert, warnt oder nur das letzte Stück Text enthält, also füge es einfach ein.
quelle
Es ist auch der Punkt, diff Geschichte zu halten. Wenn eine Datei ohne ein Zeilenumbruchzeichen endet, wird das Hinzufügen von Elementen am Ende der Datei von diff-Dienstprogrammen als Änderung der letzten Zeile angesehen (da
\n
sie hinzugefügt wird).Dies kann zu unerwünschten Ergebnissen bei Befehlen wie
git blame
und führenhg annotate
.quelle