Ask Your Question
2

jak zatarovat soubory z findu [closed]

asked 2015-04-28 00:59:38 +0100

Petr Gondek gravatar image

Triviální příklad: zaarchivujte (případně i zkomprimujte) všechny soubory které ...

find . -exec tar rf ahoj.tar "{}" \;
find . -exec tar cf - "{}" \; | gzip > ahoj.tar.gz

Proč v souboru ahoj.tar mam všechny soubory zaarchivované 2x?
Jak správně zaarchvivat všechny soubory, které find nalezne?
Druhý tar s gzipem se tváří, že funguje krásně, ale je opravdu správně?

edit retag flag offensive reopen delete

The question has been closed for the following reason "the question is answered, right answer was accepted" by Petr Gondek
close date 2015-05-15 12:49:49.949764

2 Answers

Sort by » oldest newest most voted
2

answered 2015-04-28 08:03:04 +0100

Josef Kokeš gravatar image

updated 2015-04-28 08:11:18 +0100

Obvykle opravuje Vojta mě, tak teď mu to vrátím :-)

Proč v souboru ahoj.tar mam všechny soubory zaarchivované 2x?

Protože při archivaci adresáře se archivuje i jeho obsah, a find normálně najde i adresář. Takže ten příkaz můžeme (pro konkrétní adresářovou strukturu: mkdir pokus; cd pokus; touch a b c;) přepsat jako tar rf ahoj.tar . ./a ./b ./c a v archívu pak bude ./a jednou jako důsledek archivace . a jednou jako důsledek explicitního vyžádání si archivace ./a.

Jak správně zaarchvivat všechny soubory, které find nalezne?

Musíte přesněji specifikovat podmínky, aby tar nenacházel adresáře. To je totiž primární důvod "chyby". Potom bude vaše verze s tar rf fungovat tak, jak očekáváte.

Šlo by to i s tar cf, pokud si vzpomenete, že find -exec má dva různé ukončovací znaky a že znak + by se nám pro tenhle případ hodil. Ale i tak byste musel vyřešit ty adresáře, stejně jako byste je musel vyřešit i v dalších návrzích, které vám Vojta Myslivec napsal.

Druhý tar s gzipem se tváří, že funguje krásně, ale je opravdu správně?

Záleží na tom, co rozumíte slovem "správně". Jestli se ptáte na to, že ten archív vypadá, jako když má každý soubor jen jednou a jestli to je pravda, tak není. Když si porovnáte archiv 1 a rozbalený archiv 2, tak zjistíte, že obsah mají téměř totožný, až na to, že archiv 2 má víc nul mezi jednotlivými záznamy. Odhalit, co konkrétně to znamená, je trochu složitější, ale nakonec je to jednoduché: Archiv 1 je jeden archív. Archiv 2 je několik samostatných archivů připojených za sebe. Důvod, proč v něm vidíte jen jednu kopii každého souboru, je ten, že první samostatný archív byl vytvořen pro . a obsahuje celý obsah ., další samostatné archivy jsou vytvořeny pro jednotlivé soubory - ale například tar tf na Frayi ty další samostatné archivy už nevidí, po prvním samostatném archivu si řekne, "jsem na konci archivu, končím". Můžete si to snadno vyzkoušet tímto skriptem:

mkdir pokus; cd pokus; touch a b c; tar cf - . > ../test.tar; touch d; tar cf - ./d >> ../test.tar; tar tf ../test.tar

Člověk by čekal, že uvidí soubory ., ./a, ./b, ./c, ./d, ale ne - ./d už je v dalším samostatném archivu a vůbec se nezobrazí, přestože v archivu je, jak se můžete přesvědčit pomocí cat ../test.tar.

edit flag offensive delete publish link more

Comments

Spis bych pouzil slova, ze doplnuji informace na zaklade aktualniho zadani :-)

VojtechMyslivec ( 2015-04-29 01:16:19 +0100 )edit
1

answered 2015-04-28 01:30:10 +0100

VojtechMyslivec gravatar image
  1. To, ze je to tam zrovna 2x zavsi na strukture daneho adresare.
    • odpovim otazkou: Jak vypada archiv, kdyz dam tar-u jako argument adresar a jak vypada, kdyz dam soubor?
    • btw find . najde i adresar . a take ten soubor ahoj.tar, ktery se vytvari find-u pod rukama
  2. Tam bude stejny problem, jenze gzip si to asi prebere a duplicity vyhodi.

Obecne: pozor na vytvareni souboru, kdyz hledas pomoci find ve stejnem adresari. Je dobre pouzit alespon ../ahoj.tar nebo podobne.

Ten prvni zpusob by asi mohl fungovat, ale omezil bych se na obycejne soubory:

 find . -type f -exec tar rf ../archiv.tar {} ";"

Alternativy

  1. Pokud bych chtel dat vystup z find jako argumenty pro tar, staci zmenit IFS treba jen na novy radek. Tim si zajistim, ze se vystup ze subshellu rozseka jen podle novych radku (novy radek ve jmene souboru dela jen nepritel).

  2. Dalsi varianta je pripravit si soubor se jmeny souboru (vystup z find) a ten predat prepinacem tar-u. Toto neni uplne standardni, na fray je to prepinac -I, na linuxu snad -T. Timto zpusobem ale opet nezamezim novym radkum ve jmene souboru.

  3. Pokud bych chtel jo hodne osetrit jmena souboru, nezbyde mi nic jineho nez pouzit akci -print0 u find a prikaz xargs s parametrem -0. To je ale uz pokrocila metoda a v ramci predmetu PS1 muzes predpokladat, ze nove radky se ve jmene souboru vyskytovat nebudou. Prvni varianta s IFS je tedy dostacujici.

uf... uz je pozde, pojdme spat ;-)

edit flag offensive delete publish link more

Comments

gzip za to fakt nemůže, viz moje odpověď.

Josef Kokeš ( 2015-04-28 08:03:45 +0100 )edit

Ano, to je pravda. find + tar c vytvoří spoustu archivů.

VojtechMyslivec ( 2015-04-28 23:18:54 +0100 )edit

Question tools

Follow
2 followers

Stats

Asked: 2015-04-28 00:59:38 +0100

Seen: 355 times

Last updated: Apr 28 '15