Comment «chat et suivre» un fichier?

31

Un fichier est en cours de téléchargement séquentiel par wget.

Si je commence à le déballer cat myfile.tar.bz2 | tar -xj, il peut déballer correctement ou échouer avec "EOF inattendu", selon ce qui est plus rapide.

Comment "attraper et suivre" un fichier, c'est-à-dire sortir le contenu du fichier vers stdout, mais ne quittez pas sur EOF, au lieu de cela, abonnez-vous à ce fichier et continuez à sortir de nouvelles parties des données, en ne sortant que si le fichier est fermé par écrivain et non rouvert dans les N secondes.


J'ai créé un script cat_and_follow basé sur la réponse de @ arielCo qui termine également taillorsque le fichier n'est plus ouvert pour l'écriture.

Vi.
la source
2
Je pense que vous recherchez la tailcommande avec son option de suivi.
keshlam
tailfonctionne également avec les fichiers binaires?
Vi.
2
Vous aimerez aussi less +F...
mikeserv
Je sais que vous avez trouvé votre solution, mais j'ai une question, pourquoi ne pas simplement faire:wget ... && tar xjvf ...
Joseph R.
@JosephR., 1. Pour gagner du temps en parallélisant; 2. Pour équilibrer la charge du système (éviter / minimiser la phase de déballage à pleins gaz gourmandes en ressources); 3. Pour éviter de vous souvenir de la commande "décompresser" plus tard (ou de la planifier) ​​ou de taper la commande chaînée en premier lieu (quand je ne suis pas encore sûr de vouloir la décompresser).
Vi.

Réponses:

22
tail +1f file

Je l'ai testé sur Ubuntu avec l'archive source de LibreOffice lors du wgettéléchargement:

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

Il fonctionne également sur Solaris 10, RHEL3, AIX 5 et Busybox 1.22.1 sur mon téléphone Android (à utiliser tail +1 -f fileavec Busybox).

arielCo
la source
1
Se fermera-t-il automatiquement une fois le téléchargement terminé? Je m'attends à ce que "suiveur" analyse /proc/*/fd/régulièrement et vérifie si le fichier est définitivement fermé.
Vi.
2
Je ne m'attendais pas à ce que cela tailfonctionne avec les fichiers binray ...
Vi.
Créé un script qui analyse /proc/../fd et la terminaison automatique.
Vi.
1
Vous n'avez pas besoin de GNU tail, je pense que l' -foption est standard. Cependant, il ne se terminera pas automatiquement une fois le téléchargement terminé.
Barmar
4
Dans Ubuntu tail +1fne fonctionne pas. Vous devez fairetail -n +1
dangonfast
11

Le problème est que vous catne savez pas que le fichier est toujours en cours d’ajout. Dès qu'il catrencontre la fin (actuelle) du fichier, il se ferme.

Vous devez faire wgetécrire sur un tube (ou FIFO) pour éviter cela.

wget -O - http://... | tar -xjf -
Hauke ​​Laging
la source
7
Ou curl, qui sort par défaut sur stdout. Et (1) -f -est redondant, tarlit depuis stdin par défaut, et (2) la plupart des tars peuvent détecter automatiquement la compression, ce qui jest souvent inutile. curl http://... | tar x
Kevin
2
Cela va télécharger sans enregistrer le fichier décompressé. Cela empêchera également la poursuite du téléchargement en cas de mauvais réseau.
Vi.
3
@Vi. Vous pouvez enregistrer le fichier en utilisant teecomme ceci curl http://… | tee ….tbz | tar -xj:, mais la reprise du téléchargement devient plus compliquée que de simplement invoquer à nouveau la même commande.
kasperd
5

Pour lire et suivre un fichier depuis le début jusqu'à son interruption:

tail -fn +1 file

Pour le démontrer, essayez ceci (en supposant Bash avec 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.

(Remarque: le +1fmentionné par d'autres est interprété comme un nom de fichier, au moins dans la tailcommande GNU .)

Ce qui précède fonctionne pour un seul fichier. La concaténation de plusieurs fichiers ne serait pas en mesure de les suivre tous de manière déterministe, sans s'accrocher au premier. Pour ' cat and follow ', en ne suivant que le dernier fichier, on peut utiliser la substitution de processus . Voici une autre démonstration:

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
la source
Cela a fonctionné pour moi alors tail +1f fileque non.
therealfarfetchd
Cette réponse est bien meilleure que tail +1flors de la combinaison avec d'autres options telles que--pid
Joseph K. Strauss