Warum würden Sie / dev / null auf irgendetwas setzen?
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:
rm file
touch file
oder ähnliches:
mv file file.old
gzip file.old
touch file
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 Legende cat /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:
cat / dev / null> wtmp # ':> wtmp' und '> wtmp' haben den gleichen Effekt.
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ür sh
Familien) funktioniert :
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
und dies wird mit allen Schalen arbeiten , um die Bourne - Syntax, wie ash
, bash
, ksh
, zsh
und die Gleichen:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
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.
echo > file
echo "" > file
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:
echo -n > file
Dieser ist auch nicht tragbar, wenn eine System V- sh
Escape-Sequenz verwendet wird. Einige Shells erstellen eine Datei mit einer Zeile " \c
":
echo "\c" > file
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.
truncate -s 0
Schließlich sind hier einige Alternativen aufgeführt, die portabel sind und die Arbeit ordnungsgemäß erledigen:
Explizites Drucken einer leeren Zeichenfolge in die Datei:
printf "" > file
Verwenden Sie den true
Befehl, der genau dem No-Op-Befehl entspricht, :
obwohl er besser lesbar ist:
true > file