J'ai un processus parallèle embarrassant qui crée une énorme quantité de fichiers presque (mais pas complètement) identiques. Existe-t-il un moyen d'archiver les fichiers "à la volée", afin que les données ne consomment pas plus d'espace que nécessaire?
Le processus lui-même accepte les paramètres de ligne de commande et imprime le nom de chaque fichier créé sur stdout. Je l'invoque avec parallel --gnu
qui s'occupe de distribuer les entrées (qui proviennent d'un autre processus) et de collecter les sorties:
arg_generating_process | parallel --gnu my_process | magic_otf_compressor
EXEMPLE SIMPLE pour la première partie du tuyau dans bash
:
for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done
À quoi pourrait magic_otf_compressor
ressembler? Il est censé traiter chaque ligne d'entrée comme un nom de fichier, copier chaque fichier dans une .tar
archive compressée (la même archive pour tous les fichiers traités!), Puis la supprimer. (En fait, il devrait suffire d'imprimer le nom de chaque fichier traité, un autre | parallel --gnu rm
pourrait se charger de supprimer les fichiers.)
Existe-t-il un tel outil? Je ne pense pas à compresser chaque fichier individuellement, cela gaspillerait beaucoup trop d'espace. J'ai examiné archivemount
(gardera le système de fichiers en mémoire -> impossible, mes fichiers sont trop gros et trop nombreux) et avfs
( je n'ai pas pu le faire fonctionner avec FUSE). Qu'est-ce que j'ai raté?
Je ne suis qu'à un pas de pirater un tel outil moi-même, mais quelqu'un doit l'avoir fait avant ...
EDIT : Essentiellement, je pense que je cherche un frontal stdin pour libtar
(par opposition au frontal de ligne de commande tar
qui lit les arguments de, eh bien, la ligne de commande).
la source
Réponses:
Il semble
tar
vouloir connaître tous les noms de fichiers à l'avance. C'est donc moins à la volée et plus après la volée.cpio
ne semble pas avoir ce problème:la source
tar
le code de pour voir qu'il y a une fonction qui retourne le prochain nom de fichier à traiter, ce qui m'a fait relire la documentation. - Donc,stdout
est dirigé vers legzip
processus via la substitution de processus, etstderr
est redirigé versstdout
lequel est traité par la prochaine étape dans le tuyau?tar
lit la liste des fichiers en premier, en utilisant l'exemple simple que j'ai ajouté à ma question. Cependant, en relisanttar
le code source , il me semble qu'il devrait lire la liste des fichiers "à la volée" s'il ne crée pas une archive incrémentielle. Malheureusement, j'ai des erreurs de compilation àtar
partir de la source ... :-(cpio
, autre quegrep -v 'blocks$'
. (head -n -1
utilise un très grand tampon ...) Rend cette solution un peu un hack, mais tanthead -n -1
utilise uniquement 16 Mo lorsqu'il est exécuté sur quelques Go de données. Vous pouvez toujours utiliser perl: perl -ne 'print $ last; $ last = $ _'Un cas classique de RTFM (tout ça!) . L'
-T
option GNUtar
lira les fichiers à archiver à partir d'un autre fichier (dans mon cas/dev/stdin
, vous pouvez également utiliser-
), et il y a même une--remove-files
option:(en utilisant la version parallèle de
xz
pour la compression, mais vous pouvez utiliser votre compresseur préféré à la place). A utiliser comme:EDIT : Comme le souligne Ole,
tar
semble lire la liste complète des fichiers avec l'-T
option pour une raison quelconque. Le test suivant le confirme:Il y a un délai d'une seconde sur mon système avant que tous les fichiers soient imprimés en même temps; en revanche, si la
tar
commande est remplacée parcat
, tous les fichiers sont imprimés lors de leur création. J'ai déposé une demande d'assistance auprès des utilisateurs de tar, voyons.EDIT ^ 2 : le plus récent
tar
de la source corrige cela. Ce n'est pas encore dans Ubuntu 13.10, mais pourrait être inclus avec 14.04.la source
D'une certaine manière, cela ne semble pas être un bon travail pour un compresseur solide (archiveurs sur bande + compression). L'insertion de fichiers l'un après l'autre ressemble à un travail
zip
ou à un autre format qui permet un accès aléatoire aux fichiers dans l'archive et une insertion incrémentielle.Le fait que les fichiers soient similaires n'aidera pas beaucoup dans les deux cas. Dans
zip
, les fichiers sont compressés séparément et dans les compresseurs solides, il y a généralement une fenêtre dans laquelle la compression a lieu.Si les fichiers sont basés sur du texte, vous pouvez stocker des différences par rapport à un seul fichier de référence. Pour le binaire, c'est un peu plus délicat mais cela peut être fait.
Il existe également un moyen formel (non pas en écriture seule, mais des systèmes de fichiers appropriés). Par exemple, les systèmes de fichiers ZFS et BTRFS offrent une compression transparente. Vous pouvez également utiliser ce http://developer.berlios.de/projects/fusecompress
la source
xz
semble fonctionner avec une taille de dictionnaire par défaut de 8M (au niveau de compression par défaut-6
), ce qui semble être suffisant pour mon cas d'utilisation. - Les différences avec un fichier de référence sont agréables, mais nécessitent de construire d'abord un fichier de référence. Un système de fichiers compressé détecterait-il des fichiers dont le contenu est presque identique?btrfs
a une copie sur écriture, donc si vous copiez un fichier et modifiez une partie de celui-ci, il enregistre uniquement les parties que vous avez modifiées. Si vous ne créez pas de fichiers de cette façon, il existe supposément des outils de déduplication , mais cebtrfs
n'est pas encore un système de fichiers mature et stable et la déduplication en est aux premiers stades de développement. Mais maintenant j'y pense, qu'en est-il de lessfs.com/wordpressCela peut ne pas sembler évident, mais je parie que ce
squashfs
serait parfait pour cela - et il est même implémenté dans le noyau. Depuis la version 4.1squashfs
peut gérer les pseudo-fichiers comme spécifié sur lamksquash
ligne de commande ou via un shell-script etmksquashfs
générera les fichiers lors de la création de l'archive.Il peut gérer des tuyaux - par exemple, vous pouvez capturer un autre processus
stdout
dans une archive squash montable - même fifos - c'est plutôt cool. Dans votre cas, si vous pouviez travailler la logistique de script de la tuyauterie de sortie de votre processus à travers elle, vous pouvez envelopper votre processus entièrement dansmksquashfs
et le vent avec une seule archive. Voici un peu de lareadme
façon dont cela fonctionne et il y en a plus ici :la source
test
et un fichierfile
dans ce répertoire. Pourriez-vous s'il vous plaît fournir un bref exemple?