cat /dev/null > file.txt
ist eine nutzlose Verwendung von Katze .
Im Grunde führt das cat /dev/null
einfach dazu, dass cat
nichts ausgegeben wird. Ja, es funktioniert, aber es wird von vielen missbilligt, weil es dazu führt, dass ein externer Prozess aufgerufen wird, der nicht erforderlich ist.
Es ist eines dieser Dinge, die einfach deshalb gemeinsam sind, weil sie gemeinsam sind.
Die Verwendung von just > file.txt
funktioniert bei den meisten Shells, ist jedoch nicht vollständig portierbar. Wenn Sie vollständig portabel sein möchten, bieten sich folgende Alternativen an:
true > file.txt
: > file.txt
Beide :
und true
geben keine Daten aus und sind Shell-Builtins (wohingegen cat
es sich um ein externes Dienstprogramm handelt), daher sind sie leichter und "richtiger".
Aktualisieren:
Wie tylerl in seinem Kommentar erwähnt hat, gibt es auch die >| file.txt
Syntax.
Die meisten Shells haben eine Einstellung, die verhindert, dass sie eine vorhandene Datei über abschneiden >
. Sie müssen >|
stattdessen verwenden. Dies soll menschliches Versagen verhindern, wenn Sie wirklich anhängen wollten >>
. Sie können das Verhalten mit einschalten set -C
.
Daher denke ich, dass die einfachste, geeignetste und portabelste Methode zum Abschneiden einer Datei ist:
:>| file.txt
:
auch von POSIX eingebaut werden und unterscheidet sich tatsächlich darin,true
dass es als "spezielles" eingebaut gilt .>| file
ist eine explizite abgeschnitten.true
nicht eingebaut werden und war es traditionell nicht.:
ist in allen Schalen der Familie Bourne verbaut.:
ist ein spezielles Feature für POSIX (: > file
wird also die Shell verlassen, wennfile
sie nicht zum Schreiben in POSIX-Shells geöffnet werden kann) undtrue
nicht. POSIX erwähnt sogar, dass dies:
möglicherweise effizienter ist alstrue
auf einigen Systemen.In Bezug auf die Portabilität:
Anmerkungen:
sh
oderksh
Emulation wird für Umleitungen ohne Befehl in zsh ein Standardbefehl angenommen (cat
andernfalls ein Pager für die Standardumleitung ), der mit den Variablen NULLCMD und READNULLCMD optimiert werden kann. Das ist inspiriert von der ähnlichen Funktion in(t)csh
:
In UnixV7 wurden Umleitungen zunächst nicht durchgeführt, da dies:
auf halbem Weg zwischen einem Kommentar-Leader und einem Null-Befehl interpretiert wurde. Später waren sie und wie für alle Builtins, wenn die Umleitung fehlschlägt, verlässt das die Shell.:
eval
Wenn die Umleitung fehlschlägt und spezielle integrierte Funktionen verwendet werden, wird die Shell beendet (bash
nur im POSIX-Modus).(t)csh
definiert dies ein Null-Label (fürgoto
), sodassgoto ''
dort eine Verzweigung stattfinden würde. Wenn die Umleitung fehlschlägt, wird die Shell beendet.$PATH
( im:
Allgemeinen ist das nicht,true
,cat
,cp
und imprintf
Allgemeinen ist (POSIX verlangt , dass sie)).file
es sich jedoch um einen Symlink zu einer nicht vorhandenen Datei handelt,cp
lehnen einige Implementierungen wie GNUs die Erstellung ab.In Bezug auf die Lesbarkeit:
(Dieser Abschnitt ist sehr subjektiv)
> file
. Das>
sieht zu sehr nach einer Eingabeaufforderung oder einem Kommentar aus. Auch die Frage, die ich beim Lesen stellen werde (und die meisten Shells beschweren sich über dasselbe), lautet: Welche Ausgabe leiten Sie genau um? .: > file
.:
wird als No-Op-Befehl bezeichnet. Das liest sich also gleich so, als würde eine leere Datei erzeugt. Auch hier:
kann dies jedoch leicht übersehen und / oder als Aufforderung angesehen werden.true > file
: Was hat Boolescher Wert mit Umleitung oder Dateiinhalt zu tun? Was ist hier gemeint? fällt mir als erstes ein, wenn ich das lese.cat /dev/null > file
. Verketten/dev/null
infile
?cat
Oft wird es als Befehl gesehen, den Inhalt der Datei zu sichern, was immer noch Sinn macht: Sich den Inhalt der leeren Datei sichernfile
, ein bisschen wie eine verschlungene Art zu sagen,cp /dev/null file
aber dennoch verständlich.cp /dev/null file
. Kopiert den Inhalt der leeren Datei nachfile
. Sinnvoll, auch wenn jemand, der nicht weiß, wie ercp
standardmäßig vorgehen soll, denkt, dass Sie versuchen, auchfile
einnull
Gerät herzustellen .eval > file
odereval '' > file
. Führt nichts aus und leitet die Ausgabe an a umfile
. Für mich ergibt das Sinn. Seltsam, dass es keine alltägliche Redewendung ist.printf '' > file
: druckt explizit nichts in eine Datei. Derjenige, der mir am meisten Sinn macht.In Bezug auf die Leistung
Der Unterschied wird sein, ob wir eine eingebaute Shell verwenden oder nicht. Wenn nicht, muss ein Prozess gegabelt, der Befehl geladen und ausgeführt werden.
eval
wird garantiert in allen Schalen gebaut.:
ist überall dort eingebaut, wo es verfügbar ist (Bourne / csh likes).true
ist nur in Bourne-ähnlichen Shells eingebaut.printf
ist in modernste Bourne-artige Muscheln eingebaut undfish
.cp
und sind in dercat
Regel nicht eingebaut.cp /dev/null file
Ruft jetzt keine Shell-Umleitungen auf, also Dinge wie:effizienter sein als:
(wenn auch nicht unbedingt als:
).
Persönlich
Persönlich verwende ich
: > file
in Bourne-ähnlichen Muscheln und verwende heutzutage nichts anderes als Bourne-ähnliche Muscheln.quelle
dd of=file count=0
?dd
(wie mindestens Solaris 10)count=0
ignoriert.dd if=/dev/null of=file
wäre tragbarer. In jedem Fall ist das unabhängig von der Shell.cp /dev/null file
, oder?cp /dev/null file
ist eine verbreitete Redewendung. Ich beschränke mich auf diese, es geht nicht darum, alle möglichen Wege aufzulisten.Vielleicht möchten Sie sich ansehen
truncate
, was genau das bewirkt: eine Datei abschneiden.Beispielsweise:
Dies ist wahrscheinlich langsamer als die Verwendung
true > file.txt
.Mein Hauptpunkt ist jedoch:
truncate
Ist zum Abschneiden von Dateien gedacht, während die Verwendung von> den Nebeneffekt hat, eine Datei abzuschneiden.quelle
truncate
, in dem verfügbar wäre, aber weder C-Bibliotheken>
nochunistd
Bibliotheken verfügbar wären?truncate
ist ein FreeBSD-Dienstprogramm, das vor relativ kurzer Zeit (2008) zu den GNU-Coreutils hinzugefügt wurde (obwohl der--size
GNU-Long-Option-Stil GNU-spezifisch ist). Ich würde nicht sagen, dass es tragbar ist.cp /dev/null file
würde ohne eine Shell-Umleitung funktionieren und wäre portabler.Die Antwort hängt ein bisschen davon ab, was
file.txt
ist und wie der Prozess darauf schreibt!Ich werde einen allgemeinen Anwendungsfall anführen: Sie haben eine wachsende Protokolldatei mit dem Namen
file.txt
und möchten sie drehen.Deshalb kopieren Sie zum Beispiel
file.txt
infile.txt.save
und kürzen dann abfile.txt
.In diesem Szenario IF die Datei nicht geöffnet wird
another_process
(zB:another_process
könnte ein Programm Ausgabe auf diese Datei, zum Beispiel ein Programm Protokollierung etwas), dann zwei Vorschläge sind gleichwertig und beide arbeiten gut (aber die zweite wird als die bevorzugte erste "cat / dev / null> file.txt" ist eine nutzlose Verwendung von Cat und öffnet und liest auch / dev / null).Aber das eigentliche Problem wäre, wenn der
other_process
noch aktiv ist und noch ein offenes Handle zur Datei.txt hat.Je nachdem, wie
other process
die Datei geöffnet wurde, treten zwei Hauptfälle auf :Wenn
other_process
es auf die normale Weise geöffnet wird, zeigt das Handle weiterhin auf die frühere Position in der Datei, z. B. mit einem Versatz von 1200 Byte. Der nächste Schreibvorgang beginnt daher bei Offset 1200, und Sie haben wieder eine Datei mit 1200 Bytes (+ was auch immer other_process geschrieben hat), mit 1200 führenden Nullzeichen! Ich nehme an, nicht das, was du willst .Wenn der Zeiger im "Anfügemodus"
other_process
geöffnetfile.txt
wird, sucht er bei jedem Schreiben aktiv nach dem Ende der Datei. Wenn Sie es abschneiden, wird es daher bis Byte 0 "suchen", und Sie werden nicht die schlechten Nebenwirkungen haben! Das ist was du willst (... normalerweise!)Beachten Sie, dass dies bedeutet, dass Sie beim Abschneiden einer Datei sicherstellen müssen, dass alle, die
other_process
noch an diesen Speicherort schreiben, diese im Modus "Anhängen" geöffnet haben. Andernfalls müssen Sie diese stoppenother_process
und erneut starten, damit sie auf den Anfang der Datei anstatt auf den vorherigen Speicherort zeigen.Weitere Informationen finden Sie unter /programming//a/16720582/1841533. Unter /programming//a/984761/1841533 finden Sie ein kurzes Beispiel für den Unterschied zwischen der normalen Protokollierung und der Protokollierung im Anhängemodus
quelle
cat /dev/null > file
und a> file
ist acat /dev/null
und das macht keinen Unterschied für die Datei.Ich mag das und benutze es oft, weil es sauberer aussieht und nicht, dass jemand versehentlich die Eingabetaste gedrückt hat:
Sollte auch ein eingebaut sein?
quelle
echo
Implementierungen werden nicht unterstützt-n
(und würden-n<SPC><NL>
hier ausgegeben .printf '' > file.txt
Wäre portabler (zumindest auf modernen / POSIX-Systemen).