2. Porovnání verze projektu

Porovnání verze projektu #

Napište skript, který porovnává obsah zadaného adresáře a soubory uložené v zadaném archivu.

Vstup:  [přepínače] cesta_k_adresáři cesta_k_archivu

Výstup: porovnání souborů v adresáři a archivu podle nastavených přepínačů návratová hodnota je:
- 0 - pokud lze číst všechny soubory
- 1 - pokud nějaký soubor nelze přečíst
- 2 - pokud nelze vytvořit archiv nebo dočasný adresář
- 3 - chybně zadané přepínače nebo argumenty

[přepínače] -d detailní porovnání pomocí nástroje diff
            -t porovnání pouze podle času souborů
            -z vytvoření archivu se soubory, které jsou novější

Funkčnost skriptu #

Napište skript, který porovná současný stav adresáře s archivem adresáře před změnami.

Skript prochází rekurzivně pouze běžné soubory v zadaném adresáři a všech jeho podadresářích. Testovány budou pouze běžné soubory, symbolické odkazy a jiné speciální typy souborů nebudou v testech použity a není nutné je speciálně ošetřovat.

Pokud je nastaven přepínač -d, program porovná soubory z adresáře a z archivu nástrojem diff -q, pokud jsou soubory různé nebo soubor v archivu neexistuje, vytiskne relativní cestu souboru vzhledem k zadanému adresáři. Pokud diff selže z jakéhokoli důvodu (včetně nečitelnosti souboru v archivu), soubor je považován za různý.

Pokud je nastaven přepínač -t, pak se pouze porovná čas modifikace souborů a pouze pokud je soubor v adresáři novější (test -nt v bash), tak vytiskne jeho relativní cestu.

Pokud pro soubor z adresáře neexistuje soubor se stejným jménem v archivu, tak se tento soubor vypíše pro oba přepínače -d i -t.

Pokud není zadán ani přepínač -d ani přepínač -t, nebo jsou zadány oba přepínače současně, pak program skončí chybovým kódem 3.

Pokud je nastaven přepínač -z všechny soubory ze zadaného adresáře, které jsou novější, nebo se liší od souboru v archivu (podle nastaveného přepínače -d nebo -t) se uloží do archivu v aktuálním pracovním adresáři s jménem rozdil_XXX.tgz, kde XXX je nejmenší tříciferné číslo (000-999), pro které soubor rozdil_XXX.tgz neexistuje.

Archiv zachovává struktukturu adresáře relativně od zadaného adresáře. Pokud nejsou žádné změněné soubory, vytvoří se prázdný archiv pomocí tar -czf archiv.tgz --files-from /dev/null.

Chybové stavy #

Pokud nelze přečíst libovolný soubor ze zadaného adresáře, pak program musí skončit s návratovou hodnotou 1 a výpisem "Nelze zkontrolovat soubor $name" na stderr pro všechny soubory, které nelze číst, kde $name je relativní cesta souboru vzhledem k zadanému adresáři. Program nejprve projde všechny soubory, vypíše všechny nečitelné a nové soubory, vytvoří případně archiv a teprve poté skončí s chybou.

V případě, že skript nemůže vytvořit cílový soubor (pouze při nastaveném přepínači -z) pak je návratová hodnota 2 a na stderr se vypíše zpráva "Nelze vytvořit soubor $name", kde $name je soubor, který se nepodařilo vytvořit.

V případě nemožnosti vytvoření dočasného adresáře (pomocí mktemp -d) pro rozbalení archivu je návratová hodnota 2 a na stderr se vypíše zpráva "Nelze vytvořit dočasný adresář".

V případě, že všech 1000 možných jmen (rozdil_000.tgz až rozdil_999.tgz) již existuje, vypíše se chyba "Nelze vytvořit soubor rozdil_XXX.tgz" na stderr a návratová hodnota je 2.

V případě chybně zadaných přepínačů (není zadán přepínač -d ani -t nebo jsou zadány oba dva) pak je návratová hodnota 3.

Stejný výsledek je i při chybném zadání argumentů, tedy pokud nebude první argument existující čitelný adresář a druhý argument existující čitelný soubor, nebo pokud nebude zadán správný počet argumentů (2 pozicní argumenty po zpracování přepínačů), pak bude návratová hodnota 3.

V případě, že nelze rozbalit archiv (pomocí tar -xzf), je to považováno za chybu argumentů s návratovou hodnotou 3.

Neznámý přepínač je také chyba s návratovou hodnotou 3. Přepínač s chybějícím argumentem (pokud by byl vyžadován) je také chyba s návratovou hodnotou 3.

V ostatních případech bude návratová hodnota 0.

Ukázkový příklad #

Stáhněte si soubor test1.tgz a rozbalte ho ve svém adresáři. Archiv obsahuje adresář test1, v tomto adresáři podadresář projekt a soubory archiv.tgz a rozdil_000.tgz, rozdil_001.tgz a rozdil_100.tgz.

V adresáři test1 spustíte svůj skript ./compare_archiv.sh -t -z projekt archiv.tgz

Skript otestuje, zda jsou soubory z adresáře projekt v archivu a pro každý novější soubor v adresáři projekt vytiskne jeho relativní cestu a uloží všechny změněné soubory do archivu rozdil_002.tgz, který vytvoří v adresáři test1.

Nápověda #

Pro kontrolu souborů z adresáře si vytvořte dočasný adresář pomocí příkazu mktemp -d

Do tohoto dočasného adresáře rozbalte archiv pomocí tar -xzf a zde kontrolujte existenci a obsah souborů. Příkaz tar -xzf rozbaluje soubory do pracovního adresáře. Můžete si proto poznamenat pracovní adresář, ze které byl skript spuštěn, pak se přepnout cd do nově vytvořeného adresáře, zde archiv rozbalit a pak se přepnout zpět. Druhou možností je použít v příkazu tar přepínač -C, který změní cílový adresář pro uložení rozbalených souborů, tedy např. tar -xzf archiv.tgz -C /tmp/novy_temp.

Použijte příkaz diff -q pro porovnání obsahu souborů v režimu -d. Návratový kód diff -q je 0 pro stejné soubory, 1 pro různé.

Pro rekurzivní procházení adresáře použijte příkaz find "$dir" -type f který nalezne všechny regulární soubory v adresáři a podadresářích.

Po dokončení porovnání smažte všechny soubory v dočasném adresáři pomocí rm -rf a smažte i tento adresář.

Pro nalezení jména cílového archivu rozdil_XXX.tgz jednoduše zkoušejte všechna jména od 000 do 999 a první jméno souboru, který nebude existovat použijte pro název cílového archivu.

Archiv předpokládá, že soubory jsou přímo v kořeni rozbalené struktury archivu.

Při vytváření archivu rozdílů (-z) zachovejte strukturu adresářů od kořenového adresáře. Archiv se vytváří přímo ze zadaného adresáře, aby byla zachována jeho struktura. Soubory v archivu tedy budou mít pouze cestu relativní_cesta_souboru ze zadaného adresáře.

Pro prázdný archiv použijte tar -czf archiv.tgz --files-from /dev/null.

Testování #

Struktura testů #

Testování správnosti přepínačů a zadání argumentů.

Testování správnosti výsledku bez vytvoření archivu změn.

Testování správnosti výsledku s vytvořením archivu změn včetně případu prázdného archivu.

Testování chybových stavů (nečitelné soubory, nemožnost vytvoření archivu, nemožnost vytvoření dočasného adresáře).

Testovací data budou obsahovat pouze běžné soubory a adresáře. Symbolické odkazy, speciální soubory a jiné typy souborů nebudou testovány.

Odevzdání #

Povinné zadání
Název v BRUTE 02-bash-skript
Odevzdávané soubory compare_archiv.sh
Argumenty při spuštění přepínače -dtz jméno_adresáře jméno_archivu
Návratová hodnota 0 při úspěchu
1, 2, 3 při chybě popsáno výše
Výstup relativní cesty souborů, které jsou novější, nebo se liší
každá cesta na nový řádek
Chybový výstup "Nelze zkontrolovat soubor $name" → stderr
při chybě čtení ze souboru $name

"Nelze vytvořit soubor $name" → stderr
při chybě vytváření archivu se jménem $name

"Nelze vytvořit soubor rozdil_XXX.tgz" → stderr
když všech 1000 možných jmen již existuje

"Nelze vytvořit dočasný adresář" → stderr
při chybě vytváření dočasného adresáře