Antworten:
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, wenn file
sie nicht zum Schreiben in POSIX-Shells geöffnet werden kann) und true
nicht. POSIX erwähnt sogar, dass dies :
möglicherweise effizienter ist als true
auf einigen Systemen.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Anmerkungen:
sh
oder ksh
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ür goto
), sodass goto ''
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 im printf
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.(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
in file
? 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 nach file
. Sinnvoll, auch wenn jemand, der nicht weiß, wie er cp
standardmäßig vorgehen soll, denkt, dass Sie versuchen, auch file
ein null
Gerät herzustellen .eval > file
oder eval '' > file
. Führt nichts aus und leitet die Ausgabe an a um file
. 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.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 und fish
.
cp
und sind in der cat
Regel nicht eingebaut.
cp /dev/null file
Ruft jetzt keine Shell-Umleitungen auf, also Dinge wie:
find . -exec cp /dev/null {} \;
effizienter sein als:
find . -exec sh -c '> "$1"' sh {} \;
(wenn auch nicht unbedingt als:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Persönlich verwende ich : > file
in Bourne-ähnlichen Muscheln und verwende heutzutage nichts anderes als Bourne-ähnliche Muscheln.
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:
truncate --size 0 file.txt
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.
truncate
, in dem verfügbar wäre, aber weder C-Bibliotheken >
noch unistd
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
in file.txt.save
und kürzen dann ab file.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öffnet file.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 stoppen other_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
cat /dev/null > file
und a > file
ist a cat /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:
echo -n "" > file.txt
Sollte auch ein eingebaut sein?
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).