Welche Bedingungen müssen erfüllt sein, damit eine Datei eine von POSIX definierte Textdatei ist?

22

POSIX definiert eine Textdatei als:

Eine Datei, die Zeichen enthält, die in null oder mehr Zeilen angeordnet sind. Die Zeilen enthalten keine NUL-Zeichen und keine darf länger als {LINE_MAX} Byte sein, einschließlich des Zeichens <newline>. Obwohl POSIX.1-2017 nicht zwischen Textdateien und Binärdateien unterscheidet (siehe ISO C-Standard), erzeugen viele Dienstprogramme nur vorhersehbare oder aussagekräftige Ausgaben, wenn sie mit Textdateien arbeiten. Die Standarddienstprogramme, für die solche Einschränkungen gelten, geben in ihren Abschnitten STDIN oder INPUT FILES immer "Textdateien" an.

Quelle: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403

Es gibt jedoch einige Dinge, die mir unklar sind:

  1. Muss eine Textdatei eine normale Datei sein? Im obigen Auszug heißt es nicht ausdrücklich, dass die Datei eine reguläre Datei sein muss

  2. Kann eine Datei als Textdatei betrachtet werden, wenn sie nur ein Zeichen und ein Zeichen enthält (dh ein einzelnes Zeichen, das nicht mit einem Zeilenumbruch abgeschlossen wird)? Ich weiß, diese Frage klingt vielleicht pingelig, aber sie verwenden das Wort "Zeichen" anstelle von "einem oder mehreren Zeichen". Andere mögen anderer Meinung sein, aber wenn sie "ein oder mehrere Zeichen" bedeuten, denke ich, sollten sie es explizit sagen

  3. Im obigen Auszug wird auf "Zeilen" verwiesen. Ich habe vier Definitionen gefunden, deren Name Zeile enthält: "Leere Zeile", "Zeile anzeigen", "Unvollständige Zeile" und "Zeile". Soll ich daraus schließen, dass sie "Zeile" bedeuten, weil "Leer", "Anzeige" und "Unvollständig" weggelassen wurden - oder sind alle vier dieser Definitionen als Zeile im obigen Auszug enthalten?

Alle Fragen, die nach diesem Textblock gestellt werden, hängen davon ab, ob "Zeichen" "ein oder mehrere Zeichen" bedeuten:

  1. Kann ich sicher schließen, dass eine leere Datei keine Textdatei ist, da sie kein oder mehrere Zeichen enthält?

Alle Fragen, die nach diesem Textblock gestellt werden, hängen davon ab, dass im obigen Auszug eine Zeile als "Zeile" definiert ist und dass die anderen drei Definitionen, deren Name "Zeile" enthält, ausgeschlossen werden sollten:

  1. Bedeutet die "Null" in "Null oder mehr Zeilen", dass eine Datei immer noch als Textdatei betrachtet werden kann, wenn sie ein oder mehrere Zeichen enthält, die nicht mit einem Zeilenumbruch abgeschlossen sind?

  2. Bedeutet "null oder mehr Zeilen", dass, sobald eine einzelne "Zeile" (0 oder mehr Zeichen plus eine abschließende neue Zeile) ins Spiel kommt, die letzte Zeile als "unvollständige Zeile" (eine oder mehrere nicht Zeilenumbruchzeichen am Ende einer Datei)?

  3. Bedeutet "keine [keine Zeile] darf die Länge von {LINE_MAX} Byte einschließlich des Zeilenumbruchs überschreiten", dass die Anzahl der Zeichen in einer bestimmten "Zeile" in einer Textdatei begrenzt ist (abgesehen vom Wert von LINE_MAX unter Ubuntu 18.04 und FreeBSD 11.1 ist "2048")?

Harold Fischer
quelle
Gute Frage, Harold! Ermöglicht eine gute Diskussion der Terminologie. Ich wünschte, ich könnte die Frage extra mal beantworten
Sergiy Kolodyazhnyy

Antworten:

23
  1. Muss eine Textdatei eine normale Datei sein? Im obigen Auszug heißt es nicht ausdrücklich, dass die Datei eine reguläre Datei sein muss

    Nein; Der Auszug vermerkt sogar speziell die Standardeingabe als mögliche Textdatei. Andere Standarddienstprogramme, z. B. make, verwenden speziell die Zeichenspezialdatei /dev/null als Textdatei .

  2. Kann eine Datei als Textdatei betrachtet werden, wenn sie nur ein Zeichen und ein Zeichen enthält (dh ein einzelnes Zeichen, das nicht mit einem Zeilenumbruch abgeschlossen wird)?

    Dieses Zeichen muss ein <Zeilenumbruch> sein, oder dies ist keine Zeile , und daher ist die Datei, in der es sich befindet, keine Textdatei. Eine Datei, die genau Byte 0A enthält, ist eine einzeilige Textdatei. Eine leere Zeile ist eine gültige Zeile.

  3. Im obigen Auszug wird auf "Zeilen" verwiesen. Ich habe vier Definitionen gefunden, deren Name Zeile enthält: "Leere Zeile", "Zeile anzeigen", "Unvollständige Zeile" und "Zeile". Soll ich daraus schließen, dass sie "Zeile" bedeuten, weil "Leer", "Anzeige" und "Unvollständig" weggelassen wurden?

    Es ist nicht wirklich eine Folgerung, es ist nur das, was es sagt. Das Wort "Linie" wurde kontextbezogen definiert, und darum geht es hier.

  4. Kann ich sicher schließen, dass eine leere Datei keine Textdatei ist, da sie kein oder mehrere Zeichen enthält?

    Eine leere Datei besteht aus null (oder mehr) Zeilen und ist somit eine Textdatei.

  5. Bedeutet die "Null" in "Null oder mehr Zeilen", dass eine Datei immer noch als Textdatei betrachtet werden kann, wenn sie ein oder mehrere Zeichen enthält, die nicht mit einem Zeilenumbruch abgeschlossen sind?

    Nein, diese Zeichen sind nicht in Zeilen organisiert.

  6. Bedeutet "null oder mehr Zeilen", dass, sobald eine einzelne "Zeile" (0 oder mehr Zeichen plus eine abschließende neue Zeile) ins Spiel kommt, die letzte Zeile als "unvollständige Zeile" (eine oder mehrere nicht Zeilenumbruchzeichen am Ende einer Datei)?

    Es ist nicht illegal , es ist nur keine Textdatei. Ein Dienstprogramm, das die Angabe einer Textdatei erfordert, kann sich nachteilig verhalten, wenn stattdessen diese Datei angegeben wird.

  7. Bedeutet "keine [keine Zeile] darf die Länge von {LINE_MAX} Byte einschließlich des Zeilenumbruchzeichens überschreiten", dass die Anzahl der in einer bestimmten "Zeile" in einer Textdatei zulässigen Zeichen begrenzt ist

    Ja.

Diese Definition versucht nur, Grenzen zu setzen, die ein textbasiertes Dienstprogramm ( zum Beispielgrep ) definitiv akzeptiert - nichts weiter. Es steht ihnen auch frei, Dinge freizügiger anzunehmen, und das tun sie in der Praxis ziemlich oft. Sie dürfen einen Puffer mit fester Größe verwenden, um eine Zeile zu verarbeiten, anzunehmen, dass eine neue Zeile erscheint, bevor sie voll ist, und so weiter. Sie können zu viel in Sachen lesen.

Michael Homer
quelle
1
Sind Sie sich bei Punkt 2 sicher? Der Standard gibt explizit " 0 oder mehr Zeilen" an. Also printf "a" > filewürde eine Textdatei nach dieser Definition erstellen. Ihre Antwort auf 4 scheint Ihren Antworten auf 2 und 5 zu widersprechen, da Sie vorschlagen, dass touch fileeine Textdatei erstellt wird, während printf "a" > filedies nicht der Fall ist.
Terdon
4
@terdon: Ich sehe keinen Widerspruch in Michaels Antwort. Grundsätzlich scheint er zu sagen, dass eine POSIX-Textdatei eine beliebige Datei ist, deren Inhalt mit dem regulären Ausdruck (.{0,M}\n)*(implizit verankert und an beiden Enden) \nübereinstimmt , wobei eine neue Zeile und ein .beliebiges Zeichen, das keine neue Zeile ist, übereinstimmen und Mein Platzhalter für den numerischen Wert ist LINE_MAX-1. Dies impliziert insbesondere, dass eine leere Datei eine gültige Textdatei ist, die aus Nullzeilen besteht, aber dass jede nicht leere Textdatei in einer neuen Zeile enden muss (da sie sonst eine unvollständige Zeile enthalten würde und eine unvollständige Zeile keine Zeile ist ).
Ilmari Karonen
@Michael Homer Gibt es in Bezug auf die normale Datei noch andere Beispiele als / dev / null? Es handelt sich nicht wirklich um eine Textdatei, da sie ein oder mehrere Nullzeichen enthält.
Harold Fischer
1
@HaroldFischer /dev/nullist eine leere Datei. Du denkst an /dev/zero.
Michael Homer
@HaroldFischer, nein, /dev/nullliest sich so leer, als bekommst du keine Daten, wenn du es liest. Ich bin mir nicht sicher, ob es sinnvoll ist, hier nicht reguläre Dateien zu berücksichtigen, da viele von ihnen dynamischer Natur sind. Dazu gehören Pipes, Sockets und Char-Geräte, die im Grunde nur Schnittstellen zu / von einer anderen Entität transportieren. Sie enthalten keinen statischen Datensatz, daher ist es sinnvoller, die Eigenschaften der übertragenen Daten anstelle der Eigenschaften der Datei zu berücksichtigen .
ilkkachu
7

Wie von POSIX definiert:

Ja, eine Textdatei ist (im Grunde genommen):

Eine Datei, die Zeichen enthält, die in null oder mehr Zeilen angeordnet sind.

Es wäre nützlich, auch diese Definitionen aufzunehmen:

3.92 Zeichenkette

Eine zusammenhängende Folge von Zeichen, die mit dem ersten Null-Byte abgeschlossen sind und dieses enthalten.

3.195 Unvollständige Zeile

Eine Folge von mindestens einem Nicht-Newline-Zeichen am Ende der Datei.

3.206 Line

Eine Folge von null oder mehr Nicht- <newline> -Zeichen plus einem abschließenden <newline> -Zeichen.

3.243 Newline Character (<newline>)

Ein Zeichen im Ausgabestream, das angibt, dass der Druck am Anfang der nächsten Zeile beginnen soll. Dies ist das Zeichen, das in der Sprache C mit '\ n' gekennzeichnet ist. Es ist nicht spezifiziert, ob dieses Zeichen die genaue Sequenz ist, die vom System an ein Ausgabegerät übertragen wird, um die Bewegung zur nächsten Zeile durchzuführen.

3,247 NUL

Ein Zeichen, bei dem alle Bits auf Null gesetzt sind.

Beachten Sie, dass eine "Textdatei" keine NUL-Bytes enthalten darf .


So:

  1. Muss eine Textdatei eine normale Datei sein?
    Nein, das muss nicht sein. Eine "Textdatei" ist definiert als das, was sie enthält, wenn sie gelesen wird. Wenn eine Datei "null oder mehr Zeilen" enthält, handelt es sich um eine Textdatei. Einige Dateien /dev/stdinenthalten möglicherweise eine Textdatei, wenn sie zu einem bestimmten Zeitpunkt gelesen werden und nicht, wenn sie das nächste Mal gelesen werden.
  2. Kann eine Datei als Textdatei betrachtet werden, wenn sie nur ein Zeichen und nur ein Zeichen enthält?
    Nein, das ist eine unvollständige Zeile (3.195).
    Eine Textdatei darf nur nicht "unvollständige Zeilen" enthalten.
  3. Soll ich daraus schließen, dass sie "Line" bedeuten ...?
    Ja du solltest.
  4. Kann ich sicher schließen, dass es sich bei einer leeren Datei nicht um eine Textdatei handelt?
    Nein, eine leere Datei (null Zeichen) ist eine gültige "Textdatei".
    Von oben: … keine oder mehrere Zeilen… . Nullzeilen (Nullzeichen) sind eine gültige "Textdatei".
  5. … Als Textdatei betrachtet wird, wenn sie ein oder mehrere Zeichen enthält, die nicht mit einem Zeilenumbruch abgeschlossen sind?
    Nein, eine "unvollständige Zeile" ist keine (technisch) gültige "Zeile".
  6. Bedeutet die "Null" in "Null oder mehr Zeilen", dass eine Datei immer noch als Textdatei betrachtet werden kann, wenn sie ein oder mehrere Zeichen enthält, die nicht mit einem Zeilenumbruch abgeschlossen sind?
    Nein, eine unvollständige Zeile ist keine "Zeile". Eine Textdatei darf keine unvollständigen Zeilen enthalten.

  7. ... gibt es eine Beschränkung der Anzahl der Zeichen, die in einer bestimmten "Zeile" in einer Textdatei zulässig sind ...?
    Ja, eine gültige "Textdatei" darf nicht mehr als {LINE_MAX} Byte (im Gegensatz zu Zeichen) enthalten.
    Der Wert von {LINE_MAX} ist in der Datei <limits.h> angegeben
    ( siehe auch Sensible line buffer size in C? ):

    {LINE_MAX}
    Sofern nicht anders angegeben, die maximale Länge der Eingabezeile eines Dienstprogramms (entweder Standardeingabe oder eine andere Datei) in Byte, wenn das Dienstprogramm als Verarbeiten von Textdateien beschrieben wird. Die Länge beinhaltet Platz für das Nachziehen.
    Zulässiger Mindestwert: {_POSIX2_LINE_MAX}

    Für ein GNU-basiertes System gibt es kein festgelegtes Limit (außer Speicher) :

    Makro: int LINE_MAX
    Die größte Textzeile, die von den textorientierten POSIX.2-Dienstprogrammen unterstützt werden kann. (Wenn Sie die GNU-Versionen dieser Dienstprogramme verwenden, gibt es keine tatsächliche Beschränkung außer der, die durch den verfügbaren virtuellen Speicher vorgegeben ist. Die Bibliothek kann Ihnen dies jedoch auf keinen Fall mitteilen.)

    Es scheint posix_lim.h2048 zu sein (zumindest für 64-Bit-Linux-GNU-Systeme):

    $ grep -ri 'POSIX2_LINE_MAX' /usr/include/ 
    
    /usr/include/x86_64-linux-gnu/bits/xopen_lim.h:#define NL_LANGMAX       _POSIX2_LINE_MAX
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define _POSIX2_LINE_MAX                2048
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define LINE_MAX                _POSIX2_LINE_MAX
    

    Es kann auch mit dem POSIX- Dienstprogramm getconf gefunden werden :

    $ getconf LINE_MAX
    2048
    

Verwandte Themen : Warum sollten Textdateien mit einem Zeilenumbruch enden?

Isaac
quelle
2
Diese Antwort ist größtenteils richtig, aber die richtige Antwort auf "Muss eine Textdatei eine reguläre Datei sein?" Lautet " Nein" . Jede Art von Datei kann eine Textdatei sein, es ist eine Frage des Inhalts, der Dateityp ist irrelevant. Das fileDienstprogramm gibt nur den Dateityp für spezielle Dateien an, aber so funktioniert das Dienstprogramm, verwendet file - <…oder (Linux) file -s …, um seine Heuristiken für den Dateiinhalt einer speziellen Datei anzuzeigen. Eine spezielle Datei kann bei jedem Öffnen einen anderen Inhalt haben, es kann sich also jedes Mal um eine Textdatei handeln. /dev/nullist immer eine Textdatei, da der Inhalt immer eine Textdatei ist.
Gilles 'SO - hör auf böse zu sein'
1
Anstatt grepauf Dateien zuzugreifen, können Sie getconfSystemkonfigurationswerte abrufen getconf LINE_MAX, die auf meinem System (Ubuntu 16.04) übrigens 2048 (Bytes) zurückgeben.
heemayl
Ich wollte die Datei finden, in der die Variable definiert wurde, daher war grep notwendig und erledigte die Arbeit (ziemlich schnell). Aber ja, getconferlaubt es, den aktuellen Wert von config zu lesen.
Isaac