Inhalt einer Textdatei leeren

16

Ich habe eine Textdatei in meinem Home-Verzeichnis, die regelmäßig über einen Cron-Job Daten empfängt. Da der Cron-Job dynamische Daten bereitstellt, möchte ich auch einen Cron-Job zum Leeren des Dateiinhalts festlegen (die Datei muss noch vorhanden sein). Ich brauche keine Hilfe bei Cron, nur den Befehl, der beim Leeren der Datei helfen kann.

Sosytee
quelle
5
Alternative: tail -n +1000 file.txt > file.txtsollte 1000 Zeilen entfernen und die neuesten Zeilen in der Datei behalten (Sie wissen nie, wann Sie einen Teil des letzten Datensatzes benötigen, um etwas zu verfolgen).
Rinzwind
2
Das ist eigentlich eine bessere Option als das Löschen der Datei zu festgelegten Zeiten.
Bruno Pereira
1
@Rinzwind, das funktioniert nicht, da die Datei abgeschnitten wird, bevor tail versucht, sie zu lesen. Sie müssen in eine neue Datei umleiten und dann die ursprüngliche durch die neue ersetzen.
Psusi
True @psusi :) Es muss dort eine zusätzliche Umleitung geben.
Rinzwind

Antworten:

27

Der einfachste Weg:

> filename

Dies ist ein weniger offensichtlicher Weg und wahrscheinlich für andere in einem Shell-Skript weniger lesbar, aber es ist alles, was Sie brauchen.

Da >es sich nicht wirklich um einen Befehl handelt (er ist in Bash integriert), können Sie Folgendes nicht verwenden:

sudo > filename

wenn Sie keine Berechtigungen für diese Datei haben. Aber Sie können verwenden:

sudo bash -c "> filename"
Radu Rădeanu
quelle
Welche Art von Berechtigungen müssen geändert werden, weil es heißt, dass die Genehmigung verweigert wurde, ich habe bereits chmod 755 für die Datei ausgeführt, oder sollte ich einen neuen Post
erstellen
@sosytee Siehe meine neuen Änderungen.
Radu Rădeanu
1
@sosytee Natürlich können Sie, aber verwenden Sie sudo crontab -e, um den Cron-Job für root hinzuzufügen, nicht für Sie. Oder die Datei ändert die Erlaubnis, 766 (oder 666), nicht auf 755: sudo chmod 766 filename. Weitere Informationen
Radu Rădeanu
1
truncate filenameist ein wenig sauberer und einfacher als das Umleiten leerer Ausgaben in die Datei und stößt nicht auf Probleme mit sudo.
Psusi
1
@psusi truncate -s 0 filenamekann in der Tat den Trick machen. Sie können es als Antwort hinzufügen.
Radu Rădeanu
19

Zu diesem Zweck wurde ein Tool erstellt:

truncate -s 0 filename

Dadurch wird der Inhalt gelöscht, es bleibt jedoch die gleiche Datei (die Inode bleibt gleich).

Dies ist wichtig, da einige Programme ein Handle auf die Datei "by inode" haben. Angenommen, Sie "leeren" eine Datei mithilfe der naiven Methode zum Löschen und Neuerstellen der Datei. Einige Programme behalten möglicherweise immer noch ein Handle für die alte Datei (mit dem alten Inhalt), auch wenn sie nicht mehr wie gewohnt sichtbar ist ls.

Einige Links zu weiteren Details am Ende dieser Antwort.


Ein anderer Weg, vielleicht leichter zu merken:

echo -n > filename

Dies hält auch die gleiche Inode.

Beachten Sie, dass beide truncateund echo -nnicht von POSIX definiert werden .

Für die POSIX-Konformität verwenden Sie cat /dev/null:

cat /dev/null > filename

Noch ein anderer Weg, obskurer und wahrscheinlich nicht Shell-Agnostiker:

> filename

Wenn die zu schneidende Datei zum Schreiben Root-Rechte benötigt, funktionieren die folgenden Zeilen nicht wie erwartet:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Dies liegt daran, dass die Umleitung von der Shell durchgeführt wird, noch bevor sudo ausgeführt wird. Dies bedeutet, dass der Schreibzugriff auf die Datei mit den Rechten des Benutzers erfolgt, der die Shell ausführt, nicht mit den Rechten, die von sudo gewährt werden.

Eine Problemumgehung besteht darin, die Umleitung auf eine Shell zu verschieben, die mit folgenden sudo-Berechtigungen ausgeführt wird:

sudo sh -c "echo -n > filename"

Für die Verwendung von truncatebenötigen Sie keine solche Problemumgehung, da der Schreibzugriff nicht von der Shell vorgenommen wird, sondern truncatevon sudo mit sudo-Berechtigungen ausgeführt wird.

sudo truncate -s 0 filename

Einige wichtige Informationen zu Programmen, die die Datei geöffnet halten, auch wenn die Datei gelöscht wurde, finden Sie in den folgenden Abschnitten:

lesmana
quelle
es heißt, dass die Erlaubnis verweigert wurde, chmod 755 Dateiname verwendet wurde, aber die Erlaubnis dennoch verweigert wurde
sosytee
2
Vielleicht haben Sie Noclobber in Bash aktiviert?
Lesmana
Die vollständigste Antwort bisher
AbdelHady
4

Um dies zu automatisieren, können Sie logrotate verwenden. Erstellen Sie einfach eine Konfigurationsdatei für die Datei, die geleert werden soll, fügen Sie weitere Einstellungen hinzu und Sie können sie jeden Tag automatisch anhand von Kriterien leeren lassen, die Sie beispielsweise für den täglichen Gebrauch auswählen oder wenn die Datei größer als usw. ist.

Schauen Sie sich hier an, wie Sie logrotate konfigurieren: http://linuxcommand.org/man_pages/logrotate8.html

piotrektt
quelle
1
Ich selbst bevorzuge diese Option. Wir verwenden "file> 10 Mb" -> "tar.gz it to backup" "leere Datei". Und die Backups werden nach 900 Tagen gelöscht.
Rinzwind
3

echo "" > foo_fileist eine einfache Möglichkeit, dies zu tun, wird es die gesamten Inhalt ersetzen foo_file mit „“ so dass es in diesem Fall leer.

Sie können auch verwenden cat /dev/null > foo_file, dass das Null-Gerät liest und Ihre Datei mit gar nichts überschreibt.

Bruno Pereira
quelle
es heißt, die Erlaubnis wurde verweigert, ich habe den Dateinamen chmod 755 verwendet, aber dennoch wird die Erlaubnis verweigert
sosytee
Können Sie die Dateiberechtigungen bitte mit Ihrem normalen Benutzer lesen?
Bruno Pereira
Ja, ich kann den Inhalt als normaler Benutzer lesen
inhalt