Il est important de comprendre qu'il y a un compromis ici.
tar
signifie archiveur de bande . Sur une bande, vous faites principalement de la lecture et de l'écriture séquentielles. Les bandes sont rarement utilisées de nos jours, mais tar
sont toujours utilisées pour sa capacité à lire et à écrire ses données sous forme de flux.
Tu peux faire:
tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'
Vous ne pouvez pas faire cela avec zip
ou similaire.
Vous ne pouvez même pas lister le contenu d'une zip
archive sans le stocker localement dans un fichier recherché au préalable. Pense comme:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin
ne fonctionnera pas.
Pour obtenir cette lecture rapide du contenu, zip
ou similaire, vous devez créer un index. Cet index peut être stocké au début du fichier (auquel cas il ne peut être écrit que dans des fichiers normaux, pas des flux), ou à la fin, ce qui signifie que l'archiveur doit se souvenir de tous les membres de l'archive avant de l'imprimer à la fin et signifie qu'une archive tronquée peut ne pas être récupérable.
Cela signifie également que les membres des archives doivent être compressés individuellement, ce qui signifie un taux de compression beaucoup plus faible, surtout s'il y a beaucoup de petits fichiers.
Un autre inconvénient des formats tels zip
que l'archivage est lié à la compression, vous ne pouvez pas choisir l'algorithme de compression. Découvrez comment les tar
archives étaient compressées avec compress
( tar.Z
), puis avec gzip
, puis bzip2
, puis xz
lorsque de nouveaux algorithmes de compression plus performants ont été conçus. Il en va de même pour le cryptage. Qui ferait confiance zip
au chiffrement de nos jours?
Maintenant, le problème avec les tar.gz
archives n'est pas tant que ça dont vous avez besoin pour les décompresser. La décompression est souvent plus rapide que la lecture d'un disque (vous constaterez probablement que répertorier le contenu d'une grande archive tgz est plus rapide que répertorier le même non compressé lorsqu'il n'est pas mis en cache en mémoire), mais que vous devez lire l'intégralité de l'archive.
Ne pas pouvoir lire l'index rapidement n'est pas vraiment un problème. Si vous prévoyez avoir besoin de lire souvent le contenu de la table d'une archive, vous pouvez simplement stocker cette liste dans un fichier séparé. Par exemple, au moment de la création, vous pouvez faire:
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
Un plus gros problème de l'OMI est le fait qu'en raison de l'aspect séquentiel de l'archive, vous ne pouvez pas extraire des fichiers individuels sans lire toute la section de début de l'archive qui y mène. IOW, vous ne pouvez pas faire de lectures aléatoires dans l'archive.
Maintenant, pour les fichiers recherchés, il ne doit pas en être ainsi.
Si vous compressez votre tar
archive avec gzip
, qui la comprime dans son ensemble, l'algorithme de compression utilise les données vues au début pour compresser, vous devez donc recommencer depuis le début pour décompresser.
Mais le xz
format peut être configuré pour compresser les données en morceaux individuels séparés (suffisamment grands pour que la compression soit efficace), cela signifie que tant que vous gardez un index à la fin de ces morceaux compressés, pour les fichiers recherchés, vous accédez à la données non compressées au hasard (en morceaux au moins).
pixz
(parallèle xz
) utilise cette capacité lors de la compression des tar
archives pour ajouter également un index du début de chaque membre de l'archive à la fin du xz
fichier.
Ainsi, pour les fichiers recherchés, vous pouvez non seulement obtenir une liste du contenu de l'archive tar instantanément (sans métadonnées cependant) s'ils ont été compressés avec pixz
:
pixz -l file.tar.xz
Mais vous pouvez également extraire des éléments individuels sans avoir à lire toute l'archive:
pixz -x archive/member.txt < file.tar.xz | tar xpf -
Maintenant, pourquoi des choses comme 7z
ou zip
sont rarement utilisées sur Unix est principalement parce qu'elles ne peuvent pas archiver les fichiers Unix. Ils ont été conçus pour d'autres systèmes d'exploitation. Vous ne pouvez pas faire une sauvegarde fidèle des données en utilisant ceux-ci. Ils ne peuvent pas stocker de métadonnées comme le propriétaire (identifiant et nom), l'autorisation, ils ne peuvent pas stocker de liens symboliques, de périphériques, de fifos ..., ils ne peuvent pas stocker d'informations sur les liens durs et d'autres informations de métadonnées comme des attributs étendus ou des ACL.
Certains d'entre eux ne peuvent même pas stocker des membres avec des noms arbitraires (certains s'étoufferont avec une barre oblique inversée ou une nouvelle ligne ou deux points, ou des noms de fichiers non ascii) (certains tar
formats ont cependant des limites).
Ne décompressez jamais un fichier tgz / tar.xz sur le disque!
Dans le cas où ce n'est pas évident, on n'utilise pas d' archive tgz
or tar.bz2
, tar.xz
... comme:
unxz file.tar.xz
tar tvf file.tar
xz file.tar
Si vous avez un .tar
fichier non compressé sur votre système de fichiers, c'est que vous avez fait quelque chose de mal.
L'intérêt de ces xz
/ bzip2
/ gzip
étant des compresseurs de flux est qu'ils peuvent être utilisés à la volée, dans des pipelines comme dans
unxz < file.tar.xz | tar tvf -
Bien que les tar
implémentations modernes sachent invoquer unxz
/ gunzip
/ bzip2
par elles-mêmes, alors:
tar tvf file.tar.xz
fonctionne généralement aussi (et décompresse à nouveau les données à la volée et ne stocke pas la version non compressée de l'archive sur le disque).
Exemple
Voici un arbre source du noyau Linux compressé avec différents formats.
$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
97038336 linux-4.6.7z
89468928 linux-4.6.tar.xz
Tout d'abord, comme indiqué ci-dessus, les 7z et les zip sont légèrement différents car ils ne peuvent pas y stocker les quelques liens symboliques et manquent la plupart des métadonnées.
Maintenant quelques temps pour lister le contenu après avoir vidé les caches système:
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null 0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null 8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null 0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null 0.51s user 0.15s system 89% cpu 0.739 total
Vous remarquerez que répertorier le tar.xz
fichier est plus rapide que .tar
celui même sur ce PC vieux de 7 ans, car la lecture de ces mégaoctets supplémentaires sur le disque prend plus de temps que la lecture et la décompression du fichier plus petit.
Ensuite, OK, lister les archives avec 7z ou zip est plus rapide, mais ce n'est pas un problème, comme je l'ai dit, il est facile de contourner le problème en stockant la liste des fichiers à côté de l'archive:
$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null 0.05s user 0.00s system 99% cpu 0.051 total
Encore plus rapide que 7z ou zip même après avoir laissé tomber les caches. Vous remarquerez également que la taille cumulée de l'archive et de son index est toujours inférieure à celle des archives zip ou 7z.
Ou utilisez le pixz
format indexé:
$ xzcat linux-4.6.tar.xz | pixz -9 > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null 0.04s user 0.01s system 57% cpu 0.087 total
Maintenant, pour extraire des éléments individuels de l'archive, le pire des cas pour une archive tar est lors de l'accès au dernier élément:
$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root 5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c 7.27s user 1.13s system 115% cpu 7.279 total
wc 0.00s user 0.00s system 0% cpu 7.279 total
C'est assez mauvais car il doit lire (et décompresser) toute l'archive. Comparer avec:
$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c 0.02s user 0.01s system 19% cpu 0.119 total
wc 0.00s user 0.00s system 1% cpu 0.119 total
Ma version de 7z ne semble pas être capable de faire un accès aléatoire, donc cela semble encore pire que tar.xz
:
$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
257 638 5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null 7.28s user 0.12s system 89% cpu 8.300 total
wc 0.00s user 0.00s system 0% cpu 8.299 total
Maintenant que nous en avons pixz
un généré précédemment:
$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz 1.37s user 0.06s system 84% cpu 1.687 total
tar xOf - 0.00s user 0.01s system 0% cpu 1.693 total
wc 0.00s user 0.00s system 0% cpu 1.688 total
C'est plus rapide mais toujours relativement lent car l'archive contient peu de gros blocs:
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
Il pixz
faut donc toujours lire et décompresser un gros morceau de données (jusqu'à un) ~ 19 Mo.
Nous pouvons accélérer l'accès aléatoire en rendant les archives plus petites (et en sacrifiant un peu d'espace disque):
$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2 0.17s user 0.02s system 98% cpu 0.189 total
tar xOf - 0.00s user 0.00s system 1% cpu 0.188 total
wc 0.00s user 0.00s system 0% cpu 0.187 total