Unix-Shell-Skript zum Abschneiden einer großen Datei

86

Ich versuche, ein Unix-Skript zu schreiben, das eine Datei abschneidet / leert, die kontinuierlich von einer Anwendung geschrieben / geöffnet wird, wenn sie beispielsweise 3 GB Speicherplatz erreicht. Ich weiß, dass der folgende Befehl es tun würde:

cp /dev/null [filename]

Aber ich werde dies in einer Produktionsumgebung automatisch als Cron-Job ausführen - nur hier posten, um zu sehen, ob ihr Probleme habt, während ihr etwas Ähnliches macht.

Peedee
quelle
Diese sind prod. Protokolle haben keinen Wert? Ich hatte das Glück, meine Produktionsprotokolle ein Jahr lang (in bzip2 -9 fmt) aufzubewahren, und verfügte über einige kleine Dienstprogramme, mit denen sich Joblaufzeiten und verarbeitete Datensätze leicht extrahieren ließen und die beim Laden in eine Tabelle leicht zu berechnen und Ladeverhältnisse grafisch darzustellen waren und ein paar Sachen. Wir haben ein HDWR-Problem aufgrund sinkender Lastverhältnisse entdeckt. Ja, es gibt schöne Überwachungstools, also hängt alles von Ihrer Situation ab. Haben Sie sich eine separate Option angesehen, die Ihnen logrotatemöglicherweise einen gewissen Wert bietet (aber beim Einrichten ärgerlich ist (nur raten)!).
Shellter
5
Beachten Sie, dass das Abschneiden wirksam ist, wenn die Protokolldatei mit dem Flag O_APPEND geöffnet wird. Wenn es nicht mit dem O_APPEND-Flag geöffnet wird, schreibt das Programm mit dem Offset 3 GiB (das erste Mal) weiter. Das System behandelt die ersten 3 GiB als All-Bytes-Null (was gut komprimiert wird), aber die Datei wächst weiter. Es hängt alles vom Programm ab, das das Protokoll schreibt.
Jonathan Leffler

Antworten:

115

Nur um eine weitere Antwort hinzuzufügen,

: > filename

: ist ein No-Op in Bash (POSIX-kompatibel), daher wird die Datei im Wesentlichen nur zum Schreiben geöffnet (wodurch die Datei natürlich abgeschnitten wird) und sofort geschlossen.

BEARBEITEN: Wie der Shellter kommentierte, benötigen Sie für die Umleitung keinen Befehl:

$ echo foo > foo.txt
$ cat foo.txt
foo
$ > foo.txt
$ cat foo.txt
$

Eine einfache Umleitung von selbst löscht die Datei.

chepner
quelle
24
oder einfach > filename(wie Sie sicher wissen). Viel Glück für jeden.
Shellter
5
@shelter "$> file" nicht POSIX und nicht portabel. Sie sollten den Befehl ":" no-op verwenden, bevor Sie umleiten, wie ursprünglich vorgeschlagen.
Aaron Toponce
2
+ Plus für Smiley
Chris Suszyński
2
Wie @AaronToponce hervorhob, ist "$> file" in der Tat nicht portierbar. Bei meinem Zsh-Setup hängt die Shell (angeblich wartet sie auf Eingabe). "$:> file" funktioniert in Zsh einwandfrei.
Linus Arver
1
@TechEnthusiast Es hängt von Ihren Erwartungen ab. Die Kürzung selbst ist atomar, aber Sie wissen nicht wirklich, wann sie in Bezug auf einen bestimmten Schreibvorgang auftreten wird. Sie können beispielsweise eine Teilzeile am Anfang der Datei einfügen.
Chepner
65

Ich habe den folgenden Befehl für Debian verwendet

truncate -s 0 filename
Ricardo Marimon
quelle
@SteveClay: sudo sh -c ': > filename'wird auch abgeschnittenfilename
Perleone
2
@SteveClay Der OPs-Vorschlag funktioniert auch einwandfrei mit sudo: sudo cp /dev/null filename. Ist auch cpportabel, während truncatenur modernes Linux ist.
Tino
11

Das erscheint mir vernünftig. Mit Unix können Sie dies natürlich auf 50 verschiedene Arten tun. Beispielsweise,

echo -n "" >filename
cat /dev/null >filename
Don Branson
quelle
2

trunc filename

funktioniert mit AIX-Version von UNIX

San
quelle