tee -a erstellt die Datei nicht neu

tee -a erstellt die Datei nicht neu

Ich führe den folgenden Befehl auf einem Raspberry Pi 3 in der neuesten Debian-Version aus:

cat /dev/ttyUSB0 | tee -a /media/pi/KINGSTON/klima.out | grep -F $ | tee -a /media/pi/KINGSTON/log

Der Befehl funktioniert einwandfrei und tut, was er soll; wenn ich die klima.outDatei jedoch lösche (manuell oder per CRON), wird sie nicht neu erstellt. Der Befehl wird weiterhin ausgeführt, die Protokolldatei wird weiterhin angehängt, aber die klima.outDatei kommt nicht zurück. (auch keine Pufferung). Ich möchte sie einmal pro Woche löschen, damit sie nicht über alle Grenzen hinaus wächst. Irgendwelche Vorschläge?

Antwort1

Ich gehe davon aus, dass Ihre Pipeline lange läuft und Sie versuchen, die Protokolldatei während der Ausführung zu entfernen.

Wenn Sie die Datei löschen, teeist sie für den Prozess noch zum Schreiben geöffnet, was bedeutet, dass der Speicherplatz nicht an das System zurückgegeben wird. Dies geschieht erst, wenn alle offenen Dateideskriptoren, die auf die Datei verweisen, geschlossen sind.

Es ist völlig in Ordnung, in eine gelöschte Datei zu schreiben, solange der Dateideskriptor vor dem Löschen zugewiesen wurde.

Sie müssen die Pipeline neu starten, damit die Datei neu erstellt wird und der von der alten (jetzt namenlosen) Protokolldatei belegte Speicherplatz wiederhergestellt werden kann.

Um einen Neustart der Pipeline zu vermeiden, können Sie Folgendes tun:kürzendie Datei, d. h. ihre Größe auf Null reduzieren, ohne sie zu entfernen. Dadurch können teeweitere Anhänge an die Datei angehängt werden, ohne dass sie erneut geöffnet werden muss.

Das Abschneiden einer Datei kann erfolgenwie jlliagre in seiner Antwort gezeigt hat, oder durch Verwendung truncate(eines nicht standardmäßigen Dienstprogramms, das Teil der GNU-Coreutils ist):

truncate -s 0 /media/pi/KINGSTON/klima.out

Sehendas Handbuch fürtruncatefür weitere Informationen zu diesem Dienstprogramm.

Antwort2

Wenn Sie die Dateiblöcke wiederherstellen möchten, müssen Sie die Datei löschen, nicht ihre Verknüpfung aufheben:

Diese portable Methode sollte mit den meisten Shells funktionieren:

: > /media/pi/KINGSTON/klima.out

Durch das Aufheben der Dateiverknüpfung (dh rm) wird der Verzeichniseintrag entfernt, der Dateiinhalt (Inode) wird jedoch nicht beeinflusst, solange die Datei von Lesern oder Schreibern geöffnet bleibt.

Antwort3

Sie verstehen nicht, wie das System mit Dateien umgeht.

Sie löschen den Dateieintrag, aber die Datei existiert noch, solange das Programm sie verwaltet. Sie wird also nie benachrichtigt, dass der Eintrag gelöscht wurde, und schreibt trotzdem in die Datei!

Eine eindeutige Datei kann dank der Hardlinks (erstellt durch den Befehl ln) viele Einträge haben.

Sie könnten Ihre eigene Version von tee schreiben, die die Datei bei jeder Zeile, die sie in die Datei schreibt, schließt und öffnet, die Leistung wäre jedoch sehr schlecht, da sie sehr viele Systemaufrufe generieren würde.

Hier ist eine Shell-Funktion, die ihre Eingabe auf mehrere Dateien aufteilt:

splitSizeInKio=100

splitInput(){
    local PS4='+splitInput+ '
    set -x
    local i=0
    local fname="$1"
    local ii

    while true
    do if [ $i -lt 10 ]
       then ii=0$i
       else ii=$i
       fi
       local outfile="$fname".$ii
       dd of="$outfile" bs=1024 count=$splitSizeInKio
       i=$((i+1))
    done
}

(Sie könnten „head“ statt „dd“ verwenden, wenn Sie statt einer Größe eine Zeilenanzahl angeben.)

Mit Bash können Sie die „Prozessersetzung“ wie folgt verwenden:

prog1 | tee >( splitInput somefilename ) | prog2

verwandte Informationen