In der Regel, cat /dev/null > [something]
wenn Sie den Dateiinhalt löschen und gleichzeitig sicherstellen möchten, dass das Risiko einer Unterbrechung des tatsächlichen Dateizustands absolut Null ist. Der Inhalt der Datei wird eindeutig von der cat /dev/null
Datei selbst gelöscht. Die Datei selbst, die vorhanden ist und dem Dateisystem, auf dem sie sich befindet, bekannt ist, ist weiterhin mit derselben Inode-Nummer, demselben Besitz und denselben Berechtigungen vorhanden.
Im Fall einer Protokolldatei kann es sein, dass die Protokolldatei selbst von einem anderen Prozess als "in Verwendung" markiert wird. Wenn Sie dies beispielsweise tun, rm /var/log/messages && touch /var/log/messages
würde dies andere Prozesse stören und möglicherweise dazu führen, dass laufende Prozesse ersticken. Das bedeutet, dass ein Prozess, der irgendwie an eine bestimmte Inode-Nummer gebunden ist, die mit der Datei verbunden ist, /var/log/messages
plötzlich in Panik geraten und sagen kann: „Hey! Was ist passiert? /var/log/messages
“, Auch wenn die Datei noch vorhanden ist. Ganz zu schweigen von potenziellen Problemen, bei denen Eigentum und Berechtigungen falsch wiederhergestellt werden.
Aufgrund dieser Unsicherheit in Bezug auf die Verwendung / den Status einer Datei wird die Verwendung von cat /dev/null > [something]
von Systemadministratoren bevorzugt, die ein Protokoll löschen möchten, aber den Betrieb bereits vorhandener Prozesse nicht potenziell beeinträchtigen möchten .
Auch im Zusammenhang mit der Seite , die Sie verknüpfen den Autor besagt Folgendes:
Hier gibt es nichts Ungewöhnliches, nur eine Reihe von Befehlen, die genauso einfach einzeln über die Befehlszeile auf der Konsole oder in einem Terminalfenster aufgerufen werden konnten. Die Vorteile der Platzierung der Befehle in einem Skript gehen weit über die Notwendigkeit hinaus, sie nicht immer wieder neu eingeben zu müssen.
Das „Nichts Ungewöhnliches“, das der Autor erwähnt, bezieht sich auf das gesamte Konzept dieses speziellen Bash-Skripts: Es handelt sich nur um eine Reihe einfacher Befehle, die genauso einfach über die Befehlszeile ausgeführt werden können, aber in einer Textdatei abgelegt werden vermeiden Sie es, sie immer wieder neu eingeben zu müssen.
truncate -s 0
würde das gleiche tun und weniger idiomatisch sein. Shell-Programmierer sind jedoch eine konservative Gruppe, und man könnte auf Systeme stoßen, die alt genug oder verrückt genug sind, um diesen Befehl nicht zu haben.cat /dev/null > /foo/bar
die Datei ab;echo "" > /foo/bar
schneidet es ab und schreibt dann ein einzelnes Zeilenumbruchzeichen.Sie tun dies, um den Inhalt einer Datei zu kürzen, während der Inode intakt bleibt. Alle Programme, in denen diese Datei zum Lesen oder Schreiben geöffnet ist, wären nicht betroffen, außer die Dateigröße würde auf Null zurückgesetzt.
Eine falsche Alternative, die oft gefunden wird, ist das Entfernen der Datei und das erneute Erstellen:
oder ähnliches:
Das Problem ist, dass diese Methoden nicht verhindern, dass die alte Datei von allen Prozessen geschrieben bleibt, bei denen die gelöschte Datei zum Löschzeitpunkt geöffnet ist. Der Grund, warum Sie unter Unix-Dateisystemen beim Löschen einer Datei nur deren Namen (Pfad) vom Inhalt (Inode) trennen. Die Inode bleibt so lange am Leben, wie es Prozesse gibt, bei denen sie zum Lesen oder Schreiben geöffnet ist.
Dies führt zu mehreren negativen Auswirkungen: Die Protokolle, die nach dem Löschen der Datei geschrieben wurden, gehen verloren, da das Öffnen einer gelöschten Datei nicht auf einfache / tragbare Weise möglich ist. Solange ein Prozess in die gelöschte Datei schreibt, belegt sein Inhalt immer noch Speicherplatz im Dateisystem. Das heißt, wenn Sie die Datei entfernen / erstellen, weil sie Ihren Datenträger gefüllt hat, bleibt der Datenträger gefüllt. Eine Möglichkeit, das letztere Problem zu beheben, besteht darin, die Protokollierungsprozesse neu zu starten. Möglicherweise möchten Sie dies jedoch nicht für kritische Dienste tun, und zwischengeschaltete Protokolle würden definitiv verloren gehen. Es gibt auch Nebenwirkungen, da die von Ihnen erstellte Datei möglicherweise nicht dieselben Berechtigungen, Eigentümer und Gruppen wie die ursprüngliche besitzt. Dies kann beispielsweise dazu führen, dass ein Protokollanalysator die neu erstellte Datei nicht liest oder dass der Protokollierungsprozess keine eigenen Protokolle schreibt.
Die erste Methode,
cat /dev/null > file
um das Ziel richtig zu erreichen , macht trotz einer hartnäckigen urbanen Legendecat /dev/null
absolut nichts Sinnvolles. Es öffnet eine Pseudodatei, die vom Design her leer ist, es kann nichts daraus lesen und wird schließlich einfach beendet. Die Verwendung dieses Befehls ist dann eine Verschwendung von Tastenanschlägen, Bytes, Systemaufrufen und CPU-Zyklen und kann ohne Funktionsänderung durch den zweifellos schnelleren No-Op-Befehl:
oder, bei den meisten Shells, durch überhaupt keinen Befehl ersetzt werden.Lassen Sie mich eine Metapher versuchen, um zu erklären, wie nutzlos es
cat /dev/null
ist. Nehmen wir an, Ihr Ziel ist es, ein Glas zu leeren.Sie entfernen zuerst die Flüssigkeit. Dies ist ausreichend und genau das, was (
> file
) tut, da Umleitungen immer zuerst verarbeitet werden.Dann nimmst du eine leere Flasche (
/dev/null
) und gießt sie in das leere Glas (cat
). Dies ist der sinnlose Schritt ...Wenn Sie Ihr verlinktes Dokument bis zum Ende lesen , werden Sie möglicherweise die Kommentare in dieser Zeile aus der erweiterten Version des Skripts bemerken:
Sie haben in der Tat; Schade,
cat /dev/null
wurde im Code gehalten.Das bedeutet, dass der folgende Code für alle gängigen Shells (sowohl
csh
als auch fürsh
Familien) funktioniert :und dies wird mit allen Schalen arbeiten , um die Bourne - Syntax, wie
ash
,bash
,ksh
,zsh
und die Gleichen:Beachten Sie jedoch, dass bei alten Bourne-Shells vor POSIX keiner dieser Befehle, einschließlich
cat /dev/null
, eine Datei abschneidet, wenn sie anschließend von einem noch laufenden Shellskript geschrieben wird, das daran angehängt wird. Anstelle einer Null-Byte-Datei wäre dies eine Sparse-Datei mit unveränderter Größe. Dasselbe würde passieren, wenn die Datei von einem Prozess geschrieben wird, der vor dem Schreiben nach der Position sucht, die er für die aktuelle hält.Beachten Sie auch, dass einige alternative Lösungen, die häufig zum Abschneiden einer Datei vorgeschlagen werden, Fehler aufweisen.
Die beiden folgenden erledigen den Job einfach nicht. Die resultierende Datei ist nicht leer, sondern enthält eine leere Zeile. Dies würde Protokolldateien beschädigen
wtmp
, in denen Datensätze mit fester Breite gespeichert sind.Das nächste, das auf einer BSD-
sh
Option basiert, ist nicht portierbar. POSIX gibt keine zulässigen Optionen für Echo an, sodass Sie möglicherweise eine Datei mit einer Zeile mit "-n
" erhalten:Dieser ist auch nicht tragbar, wenn eine System V-
sh
Escape-Sequenz verwendet wird. Einige Shells erstellen eine Datei mit einer Zeile "\c
":Dieser verwendet einen Befehl, der für die Ausführung der Aufgabe vorgesehen ist. Das verwendete Problem ist
truncate
nicht portierbar, da dieser von POSIX nicht angegebene Befehl auf einem Unix / Linux-System möglicherweise fehlt.Schließlich sind hier einige Alternativen aufgeführt, die portabel sind und die Arbeit ordnungsgemäß erledigen:
Explizites Drucken einer leeren Zeichenfolge in die Datei:
Verwenden Sie den
true
Befehl, der genau dem No-Op-Befehl entspricht,:
obwohl er besser lesbar ist:quelle
csh
Implementierungen, obwohl es nicht unbedingt dokumentiert ist. Von der Solaris-csh
Handbuchseite: Null command. This command is interpreted, but performs no action.
. Ich habe weder in dertcsh
Handbuchseite noch in der Original-BSD erwähntcsh
, dasselbe, aber diese Syntax hat möglicherweise immer funktioniert.cat /dev/null
besteht darin, Ihre Absichten deutlich zu machen./dev/null
, wie man Null Bytes effizient injiziert, jedenfalls zuverlässiger als mit:
oder ohne. Auf genau dieser Seite hatte Cyrus Antwort, die knapp, aber direkt auf den Punkt gebracht war, null Stimmen, während JakeGoulds, der die Tatsachecat /dev/null
in Frage stellte, ein No-Op war (siehe unsere Kommentare), bereits mindestens vier Stimmen hatte.>
oder:
ist nicht klar. Ich stimme zu, es ist eine Schande, dass Mythen aufgrund ihrer Verwendung verbreitet wurden.printf "" > file
das sowohl portabel (POSIX) als auch leicht wie eine eingebaute Shell implementiert ist.Dies ist eine umständliche Methode, um die Datei auf die Größe Null zu bringen.
quelle
csh
.: > messages
funktioniert auch.:
odertrue
sind die naheliegenderen Optionen für Befehle, die nichts ausgeben und true zurückgeben.So kürzen Sie eine geöffnete Datei. Dies ist äquivalent und verständlicher:
(Hinzugefügt -n, um den Zeilenumbruch zu vermeiden)
quelle
wtmp
Fall brechen . Siehe meine aktualisierte Antwort.bash
,-n
ist ansonsten nicht garantiert, dass es in allen Bourne-Shells funktioniert.