È importante capire che c'è un compromesso qui.
tar
significa archiviatore di nastri . Su un nastro, esegui principalmente la lettura e la scrittura sequenziale. I nastri sono usati raramente al giorno d'oggi, ma tar
sono ancora utilizzati per la sua capacità di leggere e scrivere i suoi dati come flusso.
Tu puoi fare:
tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'
Non puoi farlo con zip
o simili.
Non è nemmeno possibile elencare il contenuto di un zip
archivio senza prima memorizzarlo in un file ricercabile. Pensa come:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin
non funzionerà.
Per ottenere quella rapida lettura del contenuto zip
o simili è necessario creare un indice. Tale indice può essere memorizzato all'inizio del file (nel qual caso può essere scritto solo su file normali, non flussi) o alla fine, il che significa che l'archiviatore deve ricordare tutti i membri dell'archivio prima di stamparlo alla fine e significa che un archivio troncato potrebbe non essere recuperabile.
Ciò significa anche che i membri dell'archivio devono essere compressi singolarmente, il che significa un rapporto di compressione molto più basso, specialmente se ci sono molti piccoli file.
Un altro svantaggio con formati simili zip
è che l'archiviazione è collegata alla compressione, non è possibile scegliere l'algoritmo di compressione. Scopri come gli tar
archivi venivano compressi con compress
( tar.Z
), quindi con gzip
, quindi bzip2
, quindi con la xz
creazione di nuovi algoritmi di compressione più performanti. Lo stesso vale per la crittografia. Chi si fiderebbe zip
della crittografia al giorno d'oggi?
Ora, il problema con gli tar.gz
archivi non è tanto necessario per decomprimerli. La decompressione è spesso più rapida della lettura di un disco (probabilmente scoprirai che elencare il contenuto di un grande archivio tgz è più veloce che elencare lo stesso non compresso quando non è memorizzato nella cache), ma che devi leggere l'intero archivio.
Non essere in grado di leggere rapidamente l'indice non è davvero un problema. Se prevedi la necessità di leggere spesso il contenuto della tabella di un archivio, puoi semplicemente memorizzare tale elenco in un file separato. Ad esempio, al momento della creazione, puoi fare:
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
Un grosso problema dell'IMO è il fatto che, a causa dell'aspetto sequenziale dell'archivio, non è possibile estrarre i singoli file senza leggere l'intera sezione iniziale dell'archivio che lo conduce. IOW, non è possibile eseguire letture casuali all'interno dell'archivio.
Ora, per i file ricercabili, non deve essere così.
Se comprimi il tuo tar
archivio gzip
, che lo comprime nel suo insieme, l'algoritmo di compressione utilizza i dati visti all'inizio per comprimere, quindi devi iniziare dall'inizio per decomprimere.
Ma il xz
formato può essere configurato per comprimere i dati in singoli blocchi separati (abbastanza grande da rendere efficiente la compressione), ciò significa che finché si mantiene un indice alla fine di quei blocchi compressi, per i file ricercabili, si accede al dati non compressi in modo casuale (almeno in blocchi).
pixz
(parallelo xz
) utilizza questa funzionalità durante la compressione degli tar
archivi per aggiungere anche un indice dell'inizio di ciascun membro dell'archivio alla fine del xz
file.
Quindi, per i file ricercabili, non solo puoi ottenere immediatamente un elenco del contenuto dell'archivio tar (senza i metadati) se sono stati compressi con pixz
:
pixz -l file.tar.xz
Ma puoi anche estrarre singoli elementi senza dover leggere l'intero archivio:
pixz -x archive/member.txt < file.tar.xz | tar xpf -
Ora, il motivo per cui cose come 7z
o zip
sono usate raramente su Unix è principalmente perché non possono archiviare i file Unix. Sono stati progettati per altri sistemi operativi. Non puoi fare un backup fedele dei dati usando quelli. Non possono archiviare metadati come proprietario (ID e nome), autorizzazione, non possono archiviare collegamenti simbolici, dispositivi, strumenti di ricerca ..., non possono archiviare informazioni su collegamenti reali e altre informazioni sui metadati come attributi estesi o ACL.
Alcuni di loro non possono nemmeno archiviare membri con nomi arbitrari (alcuni si strozzeranno con barre rovesciate o newline o due punti o nomi di file non ascii) (alcuni tar
formati hanno comunque delle limitazioni).
Non decomprimere mai un file tgz / tar.xz su disco!
Nel caso in cui non sia ovvio, non si usa un tgz
o tar.bz2
, tar.xz
... archivio come:
unxz file.tar.xz
tar tvf file.tar
xz file.tar
Se hai un .tar
file non compresso nel tuo file system, è che hai fatto qualcosa di sbagliato.
Il punto centrale di questi xz
/ bzip2
/ gzip
essere compressori di flusso è che possono essere utilizzati al volo, in condotte come in
unxz < file.tar.xz | tar tvf -
Sebbene le tar
implementazioni moderne sappiano invocare unxz
/ gunzip
/ bzip2
da sole, quindi:
tar tvf file.tar.xz
generalmente funzionerebbe anche (e di nuovo decomprimerebbe i dati al volo e non memorizzerebbe la versione non compressa dell'archivio su disco).
Esempio
Ecco un albero dei sorgenti del kernel Linux compresso con vari formati.
$ 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
Innanzitutto, come notato sopra, quelli 7z e zip sono leggermente diversi perché non possono memorizzare i pochi link simbolici e mancano la maggior parte dei metadati.
Ora alcuni tempi per elencare il contenuto dopo aver svuotato le cache di sistema:
$ 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
Noterai che elencare il tar.xz
file è più veloce di .tar
quello anche su questo PC di 7 anni poiché leggere quei megabyte extra dal disco richiede più tempo della lettura e decompressione del file più piccolo.
Quindi OK, elencare gli archivi con 7z o zip è più veloce ma non è un problema come ho detto, è facilmente aggirabile memorizzando l'elenco dei file accanto all'archivio:
$ 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
Ancora più veloce di 7z o zip anche dopo aver lasciato cadere le cache. Noterai anche che la dimensione cumulativa dell'archivio e del suo indice è ancora più piccola degli archivi zip o 7z.
Oppure usa il pixz
formato indicizzato:
$ 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
Ora, per estrarre singoli elementi dell'archivio, lo scenario peggiore per un archivio tar è quando si accede all'ultimo elemento:
$ 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
È piuttosto male perché deve leggere (e decomprimere) l'intero archivio. Paragonare con:
$ 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
La mia versione di 7z sembra non essere in grado di fare l'accesso casuale, quindi sembra essere anche peggio di 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
Ora da quando ne abbiamo pixz
generato uno precedente:
$ 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
È più veloce ma ancora relativamente lento perché l'archivio contiene alcuni blocchi di grandi dimensioni:
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
Quindi pixz
deve ancora leggere e decomprimere una grande quantità di dati (fino a a) ~ 19 MB.
Possiamo rendere più veloce l'accesso casuale rendendo gli archivi blocchi più piccoli (e sacrificando un po 'di spazio su disco):
$ 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