Wie kann ich eine Datei „katzen und verfolgen“?

31

Eine Datei wird nacheinander von heruntergeladen wget.

Wenn ich mit dem Auspacken beginne cat myfile.tar.bz2 | tar -xj, kann es mit "Unexpected EOF" richtig entpacken oder fehlschlagen, je nachdem, was schneller ist.

Wie man eine Datei "cat and follow" macht, dh den Inhalt der Datei auf stdout ausgibt, aber nicht auf EOF beendet, stattdessen diese Datei abonniert hält und weiterhin neue Teile der Daten ausgibt und nur dann beendet, wenn die Datei durch geschlossen wird Schreiber und nicht innerhalb von N Sekunden wieder geöffnet.


Ich habe ein Skript cat_and_follow basierend auf der Antwort von @ arielCo erstellt, das auch beendet, tailwenn die Datei nicht mehr zum Schreiben geöffnet wird.

Vi.
quelle
2
Ich glaube, Sie suchen nach dem tailBefehl mit der Option follow.
Keshlam
tailfunktioniert das auch mit binären dateien?
Vi.
2
Das könnte dir auch gefallen less +F...
mikeserv
Ich weiß, dass Sie Ihre Lösung gefunden haben, aber ich habe eine Frage, warum nicht einfach:wget ... && tar xjvf ...
Joseph R.
@JosephR., 1. Zeit sparen durch Parallelisieren; 2. Ausgleichen der Systemlast (Vermeiden / Minimieren der ressourcenintensiven Auspackphase mit Vollgas); 3. Um zu vermeiden, dass Sie sich später an den Befehl "entpacken" erinnern (oder ihn planen) oder einen verketteten Befehl eingeben (wenn ich noch nicht sicher bin, ob ich ihn entpacken möchte).
Vi.

Antworten:

22
tail +1f file

Ich habe es unter Ubuntu mit dem LibreOffice-Quelltarball getestet, während ich es wgetheruntergeladen habe:

tail +1f libreoffice-4.2.5.2.tar.xz | tar -tvJf -

Es funktioniert auch unter Solaris 10, RHEL3, AIX 5 und Busybox 1.22.1 in meinem Android-Telefon (Verwendung tail +1 -f filemit Busybox).

arielCo
quelle
1
Wird es automatisch beendet, wenn der Download abgeschlossen ist? Ich erwarte, dass "Follower" /proc/*/fd/regelmäßig scannt und prüft, ob die Datei endgültig geschlossen ist.
Vi.
2
Ich hätte nicht tailgedacht, dass das mit Binray-Dateien funktioniert ...
Vi.
Erstellt ein Skript, das /proc/../fd scannt und automatisch beendet.
Vi.
1
Du brauchst kein GNU-Tail, ich glaube die -fOption ist Standard. Es wird jedoch nicht automatisch beendet, wenn der Download abgeschlossen ist.
Barmar
4
In Ubuntu tail +1ffunktioniert das nicht. Sie müssen tuntail -n +1
dangonfast
11

Das Problem ist, dass catnicht bekannt ist, dass die Datei noch angehängt wird. Sobald er catauf das (aktuelle) Ende der Datei stößt, wird sie beendet.

Sie müssen in wgeteine Pipe (oder einen FIFO) schreiben, um dies zu vermeiden.

wget -O - http://... | tar -xjf -
Hauke ​​Laging
quelle
7
Oder curldie standardmäßig auf stdout ausgegeben wird. Und (1) -f -ist redundant, tarliest standardmäßig von stdin und (2) die meisten tars können die Komprimierung automatisch erkennen, sodass dies jhäufig nicht erforderlich ist. curl http://... | tar x
Kevin
2
Dies wird heruntergeladen, ohne die entpackte Datei zu speichern. Außerdem wird das Fortsetzen des Downloads im Falle eines schlechten Netzwerks behindert.
Vi.
3
@Vi. Sie können die Datei mit folgendem Befehl speichern tee: Das curl http://… | tee ….tbz | tar -xjFortsetzen des Downloads ist jedoch komplizierter als das erneute Aufrufen desselben Befehls.
Kasperd
5

So lesen und verfolgen Sie eine Datei von Anfang an, bis sie unterbrochen wird:

tail -fn +1 file

Um dies zu demonstrieren, versuchen Sie dies (unter der Annahme von Bash mit GNU Coreutils):

(while true; do printf . >> /tmp/file; sleep 1; done)&
tail -fn +1 /tmp/file  # (Ctrl-C to interrupt, of course, or otherwise kill it.)
kill %  # Kills the while-loop.

(Hinweis: Das +1fvon anderen erwähnte wird zumindest im GNU- tailBefehl als Dateiname interpretiert .)

Das Obige funktioniert für eine einzelne Datei. Die Verkettung mehrerer Dateien kann nicht allen deterministisch folgen, ohne sich an der ersten zu halten. Um ' cat and follow ' nur nach der letzten Datei zu erstellen, kann die Prozessersetzung verwendet werden . Hier ist eine weitere Demonstration:

printf file1 > /tmp/file1; printf file2 > /tmp/file2
(while true; do printf . | tee -a /tmp/file{1,2} > /dev/null; sleep 1; done)&
cat /tmp/file1 <(tail -fn +1 /tmp/file2)  # (Interrupt or kill it.)
kill %  # Kills the while-loop.
James Haigh
quelle
Das hat bei mir geklappt, tail +1f fileaber nicht.
Therealfarfetchd
Diese Antwort ist viel besser als tail +1fin Kombination mit anderen Optionen wie--pid
Joseph K. Strauss