gzip, bzip2 i xz — kompresija pojedinačnih fajlova

Prva stvar koju treba razdvojiti: arhiviranje i kompresija nisu isto. tar spaja više fajlova u jedan, ali ih ne smanjuje. gzip, bzip2 i xz smanjuju jedan fajl, ali ih ne umeju spojiti.

Zato i postoji ono .tar.gz — prvo tar spoji, pa gzip stisne.

Ova stranica je o drugom delu: koji kompresor izabrati i zašto to nije svejedno.

Osnovna upotreba

Sva tri alata rade isto i imaju istu logiku:

$ ls -lh dump.sql
-rw-r--r-- 1 alen alen 512M Aug 22 09:14 dump.sql

$ gzip dump.sql
$ ls -lh dump.sql.gz
-rw-r--r-- 1 alen alen 118M Aug 22 09:14 dump.sql.gz

Original je nestao. To je najvažnija stvar koju treba zapamtiti — za razliku od većine komandi, ovi alati zamenjuju fajl umesto da naprave kopiju. Raspakivanje radi isto, obrnuto:

$ gunzip dump.sql.gz
$ ls -lh dump.sql
-rw-r--r-- 1 alen alen 512M Aug 22 09:14 dump.sql

Ako želiš da original ostane, koristi opciju -k:

$ gzip -k dump.sql
$ ls -lh dump.sql*
-rw-r--r-- 1 alen alen 512M Aug 22 09:14 dump.sql
-rw-r--r-- 1 alen alen 118M Aug 22 09:14 dump.sql.gz

Tabela imena, jer se lako pobrkaju:

gzip.gzgunzip ili gzip -d
bzip2.bz2bunzip2 ili bzip2 -d
xz.xzunxz ili xz -d

Koji izabrati

Isti fajl od 512 MB, na istoj mašini:

$ time gzip -k dump.sql
real    0m14.2s        →  118M

$ time bzip2 -k dump.sql
real    1m52.7s        →   94M

$ time xz -k dump.sql
real    4m38.1s        →   71M

Raspakivanje, isti fajlovi:

gunzip     2,1s
bunzip2   41,3s
unxz       9,8s

Iz ovoga slede tri jasna pravila:

  • gzip — kad je brzina bitna. Rotacija logova, backup koji se radi svake noći, sve što ide kroz cev. Podržan je apsolutno svuda.
  • xz — kad je veličina bitna, a pakuje se jednom. Distribucija softvera, arhiva koja se retko otvara, slanje preko spore veze.
  • bzip2 — praktično nikad. Sporiji je od gzip-a, a lošije pakuje od xz-a. Naći ćeš ga na starijim sistemima i u starim arhivama, ali za nove stvari nema razloga.

Brojevi zavise od sadržaja. Tekst i SQL dump se stiskaju odlično, a JPEG, MP4 i već zapakovana arhiva gotovo nikako — ti formati su interno već komprimovani. Pokušaj da ih dodatno stisneš samo troši vreme, a fajl ume i da poraste.

Nivoi kompresije

Sva tri alata primaju broj od 1 do 9, gde je 1 najbrže a 9 najjače:

$ gzip -1 dump.sql     # brzo, slabije
$ gzip -9 dump.sql     # sporo, jače

Podrazumevano je -6 za gzip i bzip2, a -6 i za xz. U praksi:

$ gzip -1 -k dump.sql    →  132M za 6s
$ gzip -6 -k dump.sql    →  118M za 14s
$ gzip -9 -k dump.sql    →  115M za 31s

Razlika između 6 i 9 je tri procenta, a vreme se udvostručilo. Kod gzip-a se -9 retko isplati.

Kod xz-a je priča drugačija — tamo -9 daje osetno bolji rezultat, ali traži i mnogo memorije:

$ xz -9 velika-arhiva.tar
xz: Memory usage limit reached

Za xz -9 treba oko 700 MB RAM-a pri pakovanju. Na maloj VPS mašini ili u kontejneru to je stvarni problem, pa ostani na -6.

Više jezgara

$ xz -T0 dump.sql

-T0 koristi sva dostupna jezgra i drastično skraćuje vreme — kod xz-a je to razlika između četiri minuta i jednog. Za gzip postoji zamena pigz, koja radi isto:

$ sudo apt install pigz
$ pigz dump.sql

Koliko jezgara imaš, proveravaš sa nproc.

Rad bez raspakivanja

Ovo je deo koji najviše štedi vreme u svakodnevnom radu. Ne moraš da raspakuješ log da bi ga pročitao:

$ zcat /var/log/syslog.2.gz | tail -20
$ zgrep "error" /var/log/syslog.*.gz
$ zless /var/log/syslog.3.gz
$ zdiff staro.gz novo.gz

Za bzip2 su to bzcat, bzgrep, bzless, a za xz xzcat, xzgrep, xzless.

Praktičan primer — pretraga kroz sve rotirane logove odjednom:

$ zgrep -c "Failed password" /var/log/auth.log*
/var/log/auth.log:284
/var/log/auth.log.1:1203
/var/log/auth.log.2.gz:847
/var/log/auth.log.3.gz:412

Obrati pažnju: zgrep radi i sa nekomprimovanim fajlovima, pa ovakav džoker pokriva ceo niz — o samim džokerima piše u lekciji Džokeri i navodnici.

Provera bez raspakivanja

$ gzip -l dump.sql.gz
         compressed        uncompressed  ratio uncompressed_name
          123731968           536870912  77.0% dump.sql

$ gzip -t dump.sql.gz
$ echo $?
0

Opcija -t proverava ispravnost arhive i ćuti ako je sve u redu. Vredi je pokrenuti nad backupom pre nego što obrišeš original.

Rad u lancu

Sva tri alata rade i kao filteri, što znači da mogu usred lanca:

$ mysqldump baza | gzip > backup.sql.gz

Ovo je bolje od pravljenja fajla pa pakovanja, jer nepakovana verzija nikada ne dodirne disk. Kod dumpa od 50 GB to je razlika između uspeha i punog diska.

Opcija -c šalje rezultat na standardni izlaz umesto u fajl:

$ gzip -c dump.sql > /mnt/backup/dump.sql.gz

Ovako original ostaje na mestu, a zapakovana kopija ide na drugi disk. Slanje preko mreže, bez privremenog fajla sa obe strane:

$ tar -c /home/alen | xz -T0 | ssh server 'cat > /backup/alen.tar.xz'

O spajanju komandi ovako piše u lekciji Piping i redirekcija.

Zajedno sa tar-om

tar ima zastavicu za svaki od tri alata:

$ tar -czf arhiva.tar.gz  direktorijum/     # gzip
$ tar -cjf arhiva.tar.bz2 direktorijum/     # bzip2
$ tar -cJf arhiva.tar.xz  direktorijum/     # xz

Malo j je bzip2, veliko J je xz — jedina stvar koju ovde treba zapamtiti napamet.

Pri raspakivanju zastavica nije potrebna, jer moderni tar sam prepozna format:

$ tar -xf arhiva.tar.xz

Ako ti treba nestandardan nivo kompresije unutar tar-a, ide preko promenljive:

$ XZ_OPT="-9 -T0" tar -cJf arhiva.tar.xz direktorijum/
$ GZIP="-1" tar -czf arhiva.tar.gz direktorijum/

Detaljnije o samom tar-u je na stranici tar, a pregled cele oblasti na stranici Arhiviranje i raspakivanje datoteka.

Sitnice koje ume da zabole

Kompresija ne čuva ništa osim sadržaja

Za razliku od tar arhive, .gz fajl ne pamti dozvole ni vlasništvo:

$ ls -l tajna.txt
-rw------- 1 alen alen 1024 Aug 22 10:00 tajna.txt

$ gzip tajna.txt
$ ls -l tajna.txt.gz
-rw------- 1 alen alen  412 Aug 22 10:00 tajna.txt.gz

Ovde su dozvole prenete jer je isti fajl na istom sistemu. Ali kad taj fajl prekopiraš negde drugde i tamo raspakuješ, dobija dozvole prema umask vrednosti tog korisnika. Za backup u kome dozvole moraju da prežive, koristi tar.

Kompresija nije zaštita

$ gzip tajna.txt

Ovo ne štiti ništa. Bilo ko sa pristupom fajlu raspakuje ga jednom komandom. Ako ti treba zaštita, potrebna je enkripcija:

$ gpg -c tajna.txt.gz

Više fajlova odjednom

$ gzip *.log
$ ls
app.log.gz  db.log.gz  web.log.gz

Dobio si tri odvojene arhive, ne jednu. Ako si hteo jednu, trebao ti je tar. Rekurzivno, kroz ceo direktorijum:

$ gzip -r logovi/

I ovde svaki fajl ostaje zaseban.

Fajl je već pakovan

$ gzip video.mp4
$ ls -lh video.mp4.gz
-rw-r--r-- 1 alen alen 1,1G Aug 22 11:00 video.mp4.gz

Fajl je bio 1,0 GB, a sada je 1,1 GB. Pakovanje već pakovanog sadržaja dodaje samo zaglavlje. Isto važi za .jpg, .png, .mp3, .zip i .docx.

zip nije isto što i gzip

Uprkos imenu, to su različiti alati. zip i sam spaja više fajlova, pa mu tar nije potreban — i zato je pravi izbor kad arhivu šalješ nekome ko koristi Windows. Ima ga na stranici zip i unzip.

Kratka referenca

  • gzip fajl — zapakuj (original nestaje)
  • gzip -k fajl — zadrži original
  • gzip -d fajl.gz ili gunzip fajl.gz — raspakuj
  • gzip -c fajl > drugde.gz — rezultat na izlaz
  • gzip -1 do -9 — nivo kompresije
  • gzip -l fajl.gz — odnos veličina
  • gzip -t fajl.gz — provera ispravnosti
  • zcat, zgrep, zless, zdiff — rad bez raspakivanja
  • xz -T0 — sva jezgra · pigz — višejezgarni gzip
  • tar -czf gzip · -cjf bzip2 · -cJf xz

Vežba

$ cp /var/log/syslog ~/proba.log
$ ls -lh ~/proba.log
  1. Zapakuj kopiju sa sva tri alata, čuvajući original, pa uporedi veličine i vreme izvršavanja pomoću time.
  2. Bez raspakivanja prebroj koliko redova ima u .gz verziji.
  3. Pronađi sve rotirane logove u /var/log koji sadrže reč fail, uključujući i zapakovane.
  4. Napravi arhivu celog direktorijuma /etc pakovanu xz-om, koristeći sva jezgra, a greške o nedostatku dozvola sakrij.
  5. Proveri ispravnost te arhive, pa je raspakuj u /tmp i uporedi broj fajlova sa originalom.

Za četvrti zadatak treba ti i preusmeravanje grešaka iz lekcije Piping i redirekcija.


Spajanje više fajlova u jednu arhivu je na stranici tar, a format koji radi i na Windowsu na stranici zip i unzip.

Cela lekcija je deo vodiča Linux osnove.

Comments

Popular posts from this blog

Početak u Linuxu — šta je i zašto se uči

Konverzija tipova podataka u Pythonu

groupadd