web-dev-qa-db-fra.com

Comment XZ un répertoire avec TAR en utilisant la compression maximale?

J'ai donc besoin de compresser un répertoire avec une compression maximale.

Comment puis-je le faire avec xz? Je veux dire que j'aurai aussi besoin de tar parce que je ne peux pas compresser un répertoire avec seulement xz. Existe-t-il un oneliner pour produire foo.tar.xz?

122
LanceBaynes

En supposant que xz respecte l'ensemble standard d'indicateurs de ligne de commande - y compris les indicateurs de niveau de compression, vous pouvez essayer:

tar -cf - foo/ | xz -9 -c - > foo.tar.xz 
90
Shadur

Avec un récent GNU tar sur bash ou Shell dérivé:

XZ_OPT=-9 tar cJf tarfile.tar.xz directory

le commutateur j minuscule de tar utilise bzip, le commutateur J majuscule utilise xz.

Le XZ_OPT La variable d'environnement vous permet de définir des options xz qui ne peuvent pas être transmises via des applications appelantes telles que tar.

C'est maintenant maximal .

Voir man xz pour les autres options que vous pouvez définir (-e/--extreme pourrait vous donner un avantage supplémentaire de compression pour certains jeux de données).

XZ_OPT=-e9 tar cJf tarfile.tar.xz directory
158
bsd
XZ_OPT=-9e tar cJf tarfile.tar.xz directory

est encore mieux que

XZ_OPT=-9 tar cJf tarfile.tar.xz directory
14
Evandro Jr

Si vous avez 16 GiB of RAM (et rien d'autre en cours d'exécution), vous pouvez essayer:

tar -cf - foo/ | xz --lzma2=dict=1536Mi,Nice=273 -c - > foo.tar.xz 

Cela nécessitera 1,5 GiB pour la décompression, et environ 11x celui pour la compression. Ajustez en conséquence pour des quantités moindres de mémoire.

Cela n'aidera que si les données sont réellement si grandes, et en tout cas cela n'aidera pas QUE beaucoup, mais quand même ...

Si vous compressez des fichiers binaires, ajoutez --x86 comme première option xz. Si vous jouez avec des fichiers "multimédias" (audio non compressé ou bitmaps), vous pouvez essayer avec --delta = dist = 2 (testez la valeur, les bonnes valeurs à essayer sont 1..4).

Si vous vous sentez très aventureux, vous pouvez essayer de jouer avec plus d'options LZMA, comme

--lzma2=dict=1536Mi,Nice=273,lc=3,lp=0,pb=2

(ce sont les paramètres par défaut, vous pouvez essayer des valeurs comprises entre 0 et 4, et lc + lp ne doit pas dépasser 4)

Afin de voir comment les préréglages par défaut correspondent à ces valeurs, vous pouvez vérifier le fichier source src/liblzma/lzma/lzma_encoder_presets.c. Rien de très intéressant là-bas (-e définit la longueur de Nice à 273 et ajuste également la profondeur).

10
Anonymous

Vous pouvez essayer différentes options, pour moi -4e fonctionne mieux

tar cf - wam_GG_${dir}.nc | xz -4e > wam_GG_${dir}.nc.tar.xz 

J'ai testé en exécutant:

$ tar -cf - wam_GG.nc | xz -4e > wam_GG.nc.xz
$ tar -cf - wam_GG.nc | xz -9e > wam_GG.nc.xz.2

Il semble donc que l'option -4e fonctionne un peu mieux que -9e.

$ ll wam_GG.nc.xz*
-rw-rw-r--. 1 504 504 2707596 Jan 16  2015 wam_GG.nc.xz
-rw-rw-r--. 1 504 504 2708416 Jan 16  2015 wam_GG.nc.xz.2
6
Szymon Roziewski

La commande tar utilise l'indicateur J pour les fichiers xz. Un exemple:

tar -cJvf foo.tar.xz foo/

5
leonardoav

tar --help: -I, --use-compress-program=PROG

tar -I 'xz -9' -cvf foo.tar.xz foo/  
tar -I 'gzip -9' -cvf foo.tar.gz foo/    

comprimer également avec des compresseurs externes:

tar -I 'lz4 -9' -cvf foo.tar.lz4 foo/
tar -I 'zstd -19' -cvf foo.tar.zst foo/

décompresser les compresseurs externes:

tar -I lz4 -xvf foo.tar.lz4  
tar -I zstd -xvf foo.tar.zst  

liste des compresseurs externes d'archive:

tar -I lz4 -tvf foo.tar.lz4
tar -I zstd -tvf foo.tar.zst
5
Goran Dragic

Pour ceux qui sont intéressés, -e9 est 0,4% plus petit, 20% plus lent à la compression, 3% plus lent pour la décompression, par rapport à -9 sur un ordinateur portable typique. Voici le chronométrage s'exécute sur la structure de répertoire du code source Python.

Compression:

$ Tbefore=`date +%s%3N` && XZ_OPT=-9 tar cJf python3.6.tar.9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
43.87
$ Tbefore=`date +%s%3N` && XZ_OPT=-e9 tar cJf python3.6.tar.e9xz Python-3.6.0 && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"
53.861

Décompression:

$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.395
$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf python3.6.tar.e9xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)"  && rm -rf Python-3.6.0
1.443

Taille du fichier:

$ rm -rf Python-3.6.0
$ Tbefore=`date +%s%3N` && tar xf Python-3.6.0.tar.xz && Tafter=`date +%s%3N`
$ python -c "print((float($Tafter) - float($Tbefore)) / 1000.)" && rm -rf Python-3.6.0
1.49
$ ls -al ?ython*
-rw-rw-r-- 1 hobs hobs 16378500 Dec 23 13:06 python3.6.tar.9xz
-rw-rw-r-- 1 hobs hobs 16314420 Dec 23 13:05 python3.6.tar.e9xz
-rw-rw-r-- 1 hobs hobs 16805836 Dec 23 12:24 Python-3.6.0.tar.xz
3
hobs

Dans une machine multicœur de la version v5.2.0 de xz-utils, vérifiez:

-T, --threads=NUM   use at most NUM threads; the default is 1; set to 0

Si vous souhaitez utiliser le nombre maximal de cœurs et la compression maximale:

export XZ_DEFAULTS="-9 -T 0 "

Ou réglez -T sur le nombre de cœurs que vous souhaitez utiliser.

Alors:

tar cJf target.tar.xz source

Cela peut également être utile pour choisir le niveau de compression:

https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO

2
mirix

Ce n'est pas une réponse exacte à votre question mais vous pouvez utiliser une commande au lieu de deux:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1

ajoute tous les fichiers du répertoire "dir1" à l'archive archive.7z en utilisant "ultras ettings"

les autres formats pris en charge sont: Zip, gzip, bzip2 ou tar. pour cela il suffit de remplacer 7z après -t.
--la source man 7z

REMARQUE: n'utilisez pas cette commande pour sauvegarder vos fichiers système sauf fichiers personnels parce que le format 7z ne stocke pas les permissions du système de fichiers .

1
Edward Torvalds

Si vous souhaitez que cela se termine plus rapidement, en utilisant plusieurs threads, mais sans ralentir votre système pendant que vous effectuez d'autres travaux, essayez d'ajouter -Tn où n est le nombre de threads que vous souhaitez utiliser, ainsi que Nice pour rétrograder la compression en priorité inactive.

Modèle (pour 4 fils):

tar c foo/ | Nice -n19 xz -9 -T4 > foo.tar.xz

Essayez de regarder dans top ou htop lorsque vous faites cela dans un grand répertoire (plusieurs Go). J'espère que vous devriez voir plusieurs threads xz avec une valeur Nice de 19 (priorité la plus basse).

J'ai également dépouillé cela comme aussi concis que sensé, comme: le -f - dans les autres réponses n'est tout simplement pas nécessaire, car la sortie par défaut de tar est stdout.

Vous pouvez Nice le processus tar également, mais je ne l'ai jamais trouvé nécessaire, car xz gêne toujours le CPU pour le pipeline.

Note pratique, j'utilise rarement xz -9 pour rien, pas tant à cause du CPU ou du temps, mais à cause de la forte demande en mémoire. Jetez un œil à https://catchchallenger.first-world.info/wiki/Quick_Benchmark:_Gzip_vs_Bzip2_vs_LZMA_vs_XZ_vs_LZ4_vs_LZO#Memory_requirements_on_compression . Le compresseur xz, comme bzip2, mais contrairement à gzip, utilise plus de mémoire pour des facteurs de compression plus élevés. Ajoutez à cela que xz utilise beaucoup plus de mémoire que tout autre compresseur, vous pouvez facilement utiliser plus de 600 Mo de mémoire. Et si vous utilisez le -T pour activer la compression filetée, les besoins en mémoire vont encore plus loin. Juste quelque chose à savoir, comme si vous exécutez un petit service sur un petit VM avec 1 à 2 Go de mémoire, vous pourriez par inadvertance avoir un impact.

1
Joshua Huber

Sous Mac OS X, une autre approche pour passer le paramètre avec tar consiste à utiliser un --options= drapeau. Par exemple,

tar Jcvf targetFileName.tar.xz --options='compression-level=9' directoryName
1
Samuel Li

La compression maximale dépend des capacités de l'équipement sur lequel vous souhaitez l'appliquer. Une compression maximale entraîne une extension diamétrale de sa durée, générant une lourde charge de ressources matérielles. Pour cette raison, il n'est pas recommandé de maximiser l'utilisation des ressources du serveur (CPU/RAM/Disk) to ne pas ralentir le travail des autres services qui s'exécutent dessus. Il convient de prendre en compte le compromis entre le degré de compression et sa durée/charge système.

Dans mon cas, j'ai utilisé xz sur un ordinateur portable (donc j'ai utilisé les capacités matérielles maximales) avec des paramètres sélectionnés au maximum - threads CPU, mem RAM limite et performances du disque. J'ai choisi le niveau de compression expérimentalement et cela a fonctionné le mieux (pour moi) avec l'option DictSize = 32 MiB . Ci-dessous la syntaxe de la commande utilisée

xz -k -8e -M 7000MB -T 8 -v sd-dump-rpi3b+-strech.img

où:

  • -k - compresser
  • -8e - niveau de compression
  • -M - RAM limite d'utilisation (en Go)
  • -T - nombre de threads de processeur utilisés
  • -v - mode détaillé - affiche la progression de la compression des données

Veuillez consulter prtsc ci-dessous:

enter image description here

Je n'ai délibérément pas utilisé la compression à la volée (pas d'utilisation de pipe) en raison de la limitation de la vitesse de lecture depuis la mémoire SD de mon ordinateur portable (max ~ 28 Mo/s). J'ai vidé l'image système de la carte SD sur le disque SSD avec la commande dd

Sudo dd bs=4M if=/dev/mmcblk0 > ~/Desktop/sd-dump-rpi3b+-strech.img

ou option utilisant pleinement la syntaxe dd:

Sudo dd bs=4M if=/dev/mmcblk0 of=~/Desktop/sd-dump-rpi3b+-strech.img

puis compressé. De cette façon, j'ai contourné le goulot d'étranglement de la vitesse de transfert de données qu'est la carte SD et j'ai utilisé le maximum: threads CPU, mémoire RAM et SSD (lecture/écriture ~ 540 Mo/s)

Il convient de considérer le fait que la carte SD utilisée a une capacité de 32 Go, le système utilise environ 3,6 Go sur elle. Le vidage de la carte pèse ~ 29 Go avant compression et ~ 1,7 Go après compression. L'espace vide sur la carte est de ~ 28,4 Go, qui a également été compressé avec ~ 3,6 Go de données - principalement des fichiers binaires. En supposant que 3,6 à 1,7 donne un peu plus de 50% de compression, ce qui est un effet satisfaisant avec un temps de compression de ~ 15 minutes. J'ai délibérément ignoré la compression d'espace libre, car au cours de ce processus, j'ai remarqué une réduction rapide du temps de compression à partir d'un premier calcul ~ 45 minutes et une utilisation momentanée accrue du disque SSD jusqu'à ~ 266 Mo/s (en impulsion).

Il convient de mentionner qu'à un niveau de compression élevé, un grand nombre de threads CPU (par exemple 8 threads à -9e pour moi) et la quantité de RAM non utilisable correctement, entraîne une réduction dans le nombre de threads xz (ne pas dépasser la limite d'utilisation de mémoire déclarée).

La sélection appropriée de la quantité de RAM limite de mémoire et threads CPU vous permettra de maintenir des performances adéquates et une compression rapide sans épuiser les ressources matérielles (CPU et RAM).

J'utilise dans cette recherche jachère ceci: matériel

IdeaPad Z580

  • i7-3632QM
  • 2 x 4 Go SODIMM DDR3 Synchronous PC3-12800 (1600 MHz)
  • SSD IRSSDPRS25A120

logiciel:

  • Extension Debian (x86_64)
  • Noyau 4.9.0-11-AMD64
  • xz (XZ Utils) 5.2.2
  • liblzma 5.2.2

Plus d'informations sur les possibilités d'optimisation de l'utilisation de xz dans man xz .

0
Adam Wądołkowski