Ich habe eine Logdatei, die riesig wächst. Die Informationen, die ich daraus bekommen kann, sind vernachlässigbar.
Ich möchte es mit /dev/null
verknüpfen . Aber selbst wenn es „gelöscht“ wird (siehe unten die Ausgabe von lsof), verbraucht es meinen gesamten Festplattenspeicher.
Ich kann es abschneiden mit:
: > "/proc/$pid/fd/$fd"
# for instance:
: > "/proc/2456/fd/2"
Leider gibt es Prozesse auf dem System, die angehalten werden, wenn die Festplatte voll ist, und manuell neu gestartet werden müssen (und ich möchte vermeiden, dass die Prozesse angehalten werden).
Gibt es eine Möglichkeit, die Datei automatisch zu kürzen, wenn sie zu groß wird (z. B. wenn sie mehr als 1 GB verbraucht?)
lsof
Ausgabe:
program 2456 user 2w REG 8,5 441433300992 0 21365598 /home/user/file (deleted)
Akzeptierte Antwort:
Der Inhalt einer Datei wird erst gelöscht, wenn kein Verweis mehr darauf besteht. Ein Verweis auf eine Datei kann ein Verzeichniseintrag oder ein geöffnetes Dateihandle sein. Beim Entfernen einer Datei (z.B. mit dem rm
Befehl), dass ein Prozess noch offen ist (hier der Prozess, der sich bei ihm anmeldet), bleibt der Inhalt der Datei erhalten, bis der Prozess die Datei schließt.
Der einfachste Weg, alte Protokolle loszuwerden, ist:
- Verschieben Sie die Datei unter einen anderen Namen, z.
mv foo.log foo.log.old
- Weisen Sie den Prozess an, seine Protokolldatei erneut zu öffnen. Wenn der Prozess dazu keine Möglichkeit hat, starten Sie ihn neu.
- Löschen Sie die jetzt geschlossene alte Protokolldatei (
rm foo.log.old
).
Das Programm logrotate automatisiert diesen Mechanismus und kann so konfiguriert werden, wie viele Tage alte Protokolle aufbewahrt werden sollen. Es kann auch alte Protokolle komprimieren.
Wenn Sie in Schritt 2 das Programm nicht neu starten können und es keine Möglichkeit hat, seine Protokolldatei erneut zu öffnen, können Sie versuchen, die Protokolldatei mit einem Debugger erneut zu öffnen. Beachten Sie jedoch, dass dies das Programm zum Absturz bringen kann, wenn es Informationen über die Protokolldatei enthält, die jetzt inkonsistent geworden sind. Proof-of-Concept (beachten Sie, dass dabei viele Dinge schief gehen können; im Zweifelsfall tun Sie es einfach nicht):
gdb -n $pid -batch -x /dev/stdin <<EOF
call close(2)
call open("/path/to/foo.log", 1)
EOF
Eine alternative grobe Methode, um Speicherplatz freizugeben, wenn Sie sich nicht für eines der Protokolle interessieren, besteht darin, die Datei zu kürzen. Der Protokollierungsprozess schreibt weiterhin an derselben Position in der Datei, aber die Datei wird zu einer Sparse-Datei. Wenn Sie die Datei von Anfang an lesen, erhalten Sie Nullbytes, aber diese Nullbytes belegen nur wenige kB auf der Festplatte.
dd if=/dev/null of=/path/to/foo.log