Soll ich einfache oder doppelte spitze Klammern verwenden, um nach / dev / null umzuleiten?

18

Die meisten Antworten hier [ 1 ] [ 2 ] [ 3 ] verwenden eine einzelne spitze Klammer, um nach / dev / null umzuleiten.

command > /dev/null

Das Anhängen an / dev / null funktioniert aber auch:

command >> /dev/null

Gibt es außer dem zusätzlichen Zeichen einen Grund, dies nicht zu tun? Ist eine dieser beiden Möglichkeiten "besser" für die zugrunde liegende Implementierung von / dev / null?

Edit:
Die open (2) manpage sagt lseek vor jedem Schreiben in eine Datei im Append - Modus aufgerufen wird:

O_APPEND
Die Datei wird im Append-Modus geöffnet. Vor jedem Schreiben (2) wird der Dateiversatz wie bei lseek (2) am Ende der Datei positioniert. Die Änderung des Dateioffsets und die Schreiboperation werden als ein einzelner atomarer Schritt ausgeführt.

das lässt mich denken, dass es eine kleine Leistungsstrafe für die Verwendung geben könnte >>. Andererseits scheint das Abschneiden von / dev / null eine undefinierte Operation gemäß diesem Dokument zu sein:

O_TRUNC
Wenn die Datei bereits vorhanden und eine reguläre Datei ist und der Zugriffsmodus das Schreiben zulässt (dh O_RDWR oder O_WRONLY ist), wird sie auf die Länge 0 gekürzt. Wenn die Datei eine FIFO- oder Endgerätedatei ist, wird das O_TRUNC-Flag ignoriert. Ansonsten ist die Wirkung von O_TRUNC nicht spezifiziert.

und die POSIX-Spezifikation besagt >, dass eine vorhandene Datei abgeschnitten werden soll , aber O_TRUNC ist für Gerätedateien implementierungsdefiniert und es gibt kein Wort darüber, wie / dev / null auf das Abschneiden reagieren soll .

Ist truncating / dev / null tatsächlich nicht spezifiziert? Und haben die lseek- Aufrufe einen Einfluss auf die Schreibleistung?

Morgan
quelle

Antworten:

27

Per Definition wird /dev/nullalles, was darauf geschrieben ist , gelöscht. Es spielt also keine Rolle, ob Sie im Anhänge-Modus schreiben oder nicht, alles wird verworfen. Da die Daten nicht gespeichert werden, gibt es eigentlich keine Anhänge.

Am Ende ist es also nur kürzer, > /dev/nullmit einem >Zeichen zu schreiben .

Wie für den bearbeiteten Zusatz:

Die open (2) -Manpage besagt, dass lseek vor jedem Schreiben in eine Datei im Anhänge-Modus aufgerufen wird.

Wenn du genau liest, siehst du, dass es heißt (Hervorhebung von mir):

der Dateioffset wird wie bei lseek (2) am Ende der Datei positioniert

Das bedeutet, dass der lseekSystemaufruf nicht aufgerufen wird (muss) , und der Effekt ist auch nicht derselbe: Der Aufruf lseek(fd, SEEK_END, 0); write(fd, buf, size);ohne entspricht O_APPENDnicht dem Schreiben im Anhänge-Modus, da bei separaten Aufrufen ein anderer Prozess in den schreiben könnte Datei zwischen den Systemaufrufen, die angehängten Daten zu verwerfen. Im Append-Modus geschieht dies nicht (außer über NFS, das den echten Append-Modus nicht unterstützt ).

Der Text in der Norm erwähnt lseekan dieser Stelle nicht, nur die Schreibvorgänge gehen ans Ende der Datei.

Ist truncating / dev / null tatsächlich nicht spezifiziert?

Gemessen an der Schriftstelle, auf die Sie sich beziehen, ist sie anscheinend von der Umsetzung abhängig. Das bedeutet, dass jede vernünftige Implementierung dasselbe wie bei Pipes und TTYs tut, nämlich nichts. Eine verrückte Implementierung könnte noch etwas anderes tun, und möglicherweise bedeutet Kürzung etwas Sinnvolles im Fall einer anderen Gerätedatei.

Und haben die lseek-Aufrufe einen Einfluss auf die Schreibleistung?

Probier es aus. Dies ist die einzige Möglichkeit, auf einem bestimmten System sicher zu sein. Oder lesen Sie die Quelle, um zu sehen, wo der Anfügemodus das Verhalten ändert, falls vorhanden.

ilkkachu
quelle
-3

Wenn Sie Effizienz wünschen, verwenden Sie command >&-stattdessen. Dies schließt den Dateideskriptor, anstatt ihn umzuleiten, sodass keine Zeit damit verschwendet wird, Dinge darauf zu schreiben.

db48x
quelle
3
Schließen Sie keine Streams, die kürzer als 3 sind. Dadurch werden die std * -Deskriptoren durch zufällige Dateideskriptoren ersetzt. möglicherweise mit katastrophalen Folgen.
Joshua
7
Wenn Sie nur den Dateideskriptor schließen, erhält das Programm bei jedem Schreibaufruf Fehler, die möglicherweise zu lästigen Fehlermeldungen führen und das Programm möglicherweise beenden, bevor es seine Aufgabe beendet.
ilkkachu