bLinux documentation Project (CS) / 1. Linux –příručka uživatele
Previous Content Next Up

 

11. Zábavné příkazy

    Většina lidí, která má co do činění s operačním systémem Unix, asi nebude souhlasit s titulem této kapitoly. Někteří se dokonce rozčílí, protože si u každého příkazu musejí pamatovat až desítky parametrů a najednou se jim někdo snaží namluvit, že by používání takových příkazů mohlo být zábavné. V nadpisu této kapitoly se spíý odráží až sarkastický humor autorů operačního systému Unix. Dále uvedené příkazy totiž nemají ekvivalentní příkazy v operačním systému MS-DOS. Přitom jsou velmi výkonné, a když je zatvrzelí příznivci operačního systému MS-DOS chtějí používat, musejí si je koupit (speciální verze těchto příkazů pro MS-DOS byly dodatečně vytvořeny). Protože operační systém Unix odjakživa soupeří s operačními systémy od firmy Microsoft, jsou touto skutečností příznivci operačního systému Unix pobaveni.

    V této kapitole se budeme zabývat příkazy find (příkaz pro vyhledávání skupin souborů v adresářové struktuře), tar (příkaz pro archivaci souborů nebo celých adresářů), dd (příkaz pro kopírování) a sort (příkaz pro třídění souborů). Předem je nutno upozornit na skutečnost, že tyto příkazy nejsou standardizovány. Zaměříme se na popis verzí náležejících do projektu GNU, protože právě tyto verze jsou implementovány v operačním systému Linux a právě tyto verze pravděpodobně budou (tak jako ostatní programy vytvořené v rámci projektu GNU) v blízké budoucnosti představovat standard. Používáte-li jiný operační systém typu Unix, pak nezapomeňte konfrontovat příslušné manuálové stránky.

11.1 Příkaz find

11.1.1 Všeobecné poznámky

    Mezi doposud probranými příkazy jsou takové, které umožňují rekurzivní procházení stromovou strukturou adresářů. Příkladem jsou příkazy ls -R nebo rm -R. Příkaz find je také rekurzivní. Kdykoliv byste měli něco dělat s jistým typem souborů v adresáři a ve všech jeho podadresářích, vzpomeňte si na příkaz find. V jistém smyslu platí, že vyhledávání souborů příkazem find představuje spíše vedlejší efekt. Základní struktura příkazu find je následující:

find cesta [...] výraz [...]

    Uvedená syntaxe platí pouze pro verzi GNU. Ostatní verze neumožňují specifikovat více než jednu cestu (path), což z praktického hlediska není tak důležité. Hrubé vysvětlení funkce příkazu je následující: prostřednictvím prvního parametru zadáte, odkud má prohledávání začít (parametr path; u verze GNU nemusíte tento parametr vůbec uvádět a prohledávání pak začne od aktuálního adresáře), a druhý parametr (expression) určuje typ vyhledávání.

    Standardní chování příkazu find je poněkud lstivé a stojí za to tomuto faktu věnovat trochu pozornosti. Předpokládejme, že vaším domovským adresářem je adresář garbage a že obsahuje soubor foobar. Řekněme, že náhodou napíšete příkaz find .-name foobar. Tento příkaz by měl podle všech předpokladů vyhledat soubory nazvané foobar - avšak nic se nestane. Potíž je v tom, že program find je tzv. tichý (silent) příkaz. Pouze vrátí 0 (aš už nějaký soubor najde nebo ne), nebo vrátí záporné číslo, pokud nastal nějaký problém. Uvedený případ nenastane, pokud používáte operační systém Linux, ale je dobré jej mít na paměti.

11.1.2 Výrazy

    Výraz neboli parametr expression může být rozdělen do čtyř různých skupin klíčových slov: volby, testy, akce a operátory. Každé klíčové slovo může vracet hodnotu true nebo false a přitom může produkovat nějaký vedlejší efekt. Rozdíl mezi skupinami klíčových slov popisuje následující seznam:

    Jsou-li vedle sebe uvedeny dva výrazy bez operátoru, pak se implicitně aplikuje operátor -and. Poznamenejme, že program find spoléhá na syntaktickou analýzu příkazu, kterou realizuje příkazový procesor. To znamená, že všechna klíčová slova musejí být oddělena nezobrazitelnými znaky a zejména platí, že spousta znaků musí být oddělena znaky Escape - jinak by je příkazový procesor nemohl správně interpretovat. Jako znaky Escape mohou být použita obrácená lomítka, jednoduché nebo dvojité uvozovky. V později uvedených příkladech se jednoznaková klíčová slova uvozují obráceným lomítkem, protože je to nejjednodušší.

11.1.3 Volby

    V následujícím seznamu uvádíme přehled všech voleb, které je schopen příkaz find akceptovat (připomínáme, že se jedná o verzi GNU). Nezapomeňte, že volby vždy vracejí hodnotu true.

-daystart Volba -daystart měří dobu, která uplyne od poslední půlnoci. Počítačový nadšenec asi nemůže pochopit, proč má nějaký program takovou volbu, ale programátor, který pracuje od osmi do pěti, ji ocení.
-depth Tato volba zajistí, že příkaz find bude zpracovávat obsah každého podadresáře před zpracováním adresáře samotného. Abych řekl pravdu, neumím si představit užitečné uplatnění této volby, kromě případu, kdy se emuluje příkaz rm -F (podadresáře nemůžete zrušit, dokud obsahují nějaké soubory).
 -noleaf Volba -noleaf vypíná optimalizaci, která indikuje, že adresář obsahuje o dva podadresáře méně, než by měl obsahovat. Kdyby byl svět dokonalý, pak by bylo možné odkazovat se na všechny adresáře z prostředí každého jejich podadresáře (pomocí volby ..), pomocí odkazu . uvnitř samotného adresáře a prostřednictvím jeho skutečného jména z jeho nadřazeného adresáře.
To znamená, že na každý adresář musejí existovat alespoň dva samotného a jeden z adresáře nadřazeného) a případně další odkazy ze všech podadresářů. V praxi se však může stát, že symbolické odkazy a distribuované souborové systémy mohou toto pravidlo porušit.
-maxdepth levels, -mindepth levels Parametry levels jsou nezáporná čísla, jež udávají maximální a minimální úroveň podadresářů, které má příkaz find prohledávat. Uveďme příklady: -maxdepth 0 indikuje, že příkaz find má být realizován pouze pro argumenty uvedené v příkazovém řádku a že se žádné podadresáře prohledávat nemají. -mindepth 1 zakazuje zpracování příkazu pro argumenty uvedené v příkazovém řádku, zatímco ostatní soubory v podadresářích budou zpracovány.
-version Po zadání parametru -version se pouze vypíší informace o verzi programu find.
-xdev Parametr -xdev má poněkud zavádějící označení. Pro program find předává informaci o tom, že se dané zařízení (tedy souborový systém) nemá prohledávat. Volba -xdev je velmi užitečná v případě, kdy se má vyhledávat něco v hlavním souborovém systému. Hlavní souborový systém většinou obsazuje malou diskovou oblast. Kdyby se použil příkaz find / bez parametru -xdev, pak by se prohledávala celá adresářová struktura!

 

11.1.4 Testy

    První dva testy jsou velmi jednoduché: -false vždy vrací hodnotu false a -true vždy vrací hodnotu true. K dalším testům, které nevyžadují specifikaci hodnoty, patří test empty (vrací hodnotu true, pokud je daný soubor prázdný) a dále dvojice -nouser / nogroup, kdy test vrací hodnotu true, právě když se v souboru /etc/passwd nebo /etc/group nevyskytuje záznam identifikující vlastníka souboru jako uživatele nebo skupinu. Jedná se o postižení situace, kdy je v systému zrušen účet uživatele, ale soubory jím vlastněné jsou stále uloženy někde v souborovém systému. Podle Murphyho zákonů jsou takové soubory neobyčejně velké.

    Samozřejmě je možné vyhledávat soubory vlastněné jistým uživatelem nebo jistou skupinou. Odpovídající testy jsou -uid nn a -gid nn. Naneštěstí nelze přímo zadat uživatelské jméno, ale musí se vždy uvést jeho identifikační číslo nn. Je povoleno použít zápis identifikačního čísla ve tvaru Ctrl+nn, což znamená “ostře větší než” nebo -nn, což znamená “ostře menší než”. Ve spojení s identifikačními čísly uživatelů se tato možnost jeví jako hloupá, ale v souvislosti s ostatními testy může být užitečná. Další užitečnou volbou je volba -type c, která vrací hodnotu true, pokud je soubor typu c. Mnemotechnické zkratky jsou stejné, jako v případě příkazu ls: b pro binární soubor, c pro znakový soubor, d pro adresáře, p pro pojmenované roury, l pro symbolické odkazy a s pro sokety (sockets). Obyčejné soubory jsou specifikovány prostřednictvím zkratky f. K testu -type se vztahuje test -xtype, který je podobný, ale chová se jinak v případě symbolických odkazů - pokud není zadána volba -follow, ověřuje se místo vlastního symbolického odkazu soubor, na který odkaz odkazuje.

    Testy -inum nn a -links nn ověřují, zda je číslo i-uzlu příslušné k danému souboru nn nebo zda má soubor nn symbolických odkazů. Test -size nn má hodnotu true, jestliže je pro soubor alokováno nn bloků po 512 bajtech. Dnes již však neplatí, že se velikost souboru vždy měří (například po zadání příkazu ls -s) v blocích po 512 bajtech - Linux například používá bloky po 1024 bajtech. Proto je možné číslo nn doplnit znakem b (pak se měří velikost v bajtech) nebo k (pak se měří velikost v kilobajtech).

    Bity specifikující přístupová práva se testují pomocí testu -perm mode. Pokud argumentu mode nepředchází žádné znaménko, pak bity specifikující přístupová práva musejí přesně souhlasit. Pokud předchází znaménko -, pak musejí být nastavena příslušná přístupová práva, ale o ostatních se nic nepředpokládá. Pokud předchází znak Ctrl+, pak je podmínka splněna, právě když je kterýkoliv z bitů nastaven. Důležité je, že hodnota mode musí být uvedena buď symbolicky, nebo jako oktalové číslo, tak jako v případě příkazu chmod.

    Následující skupina testů se vztahuje k času, kdy byl soubor naposledy použit. Takové testy jsou zejména užitečné tehdy, když dojde k zaplnění diskového prostoru a uživatel potřebuje vyhledat staré soubory, které lze zrušit. Staré a zapomenuté soubory se těžko hledají a příkaz find vám dává naději, že se vám je podaří nalézt. Test -atime nn vrací hodnotu true, pokud byl daný soubor zpřístupněn před nn dny, -ctime nn vrací hodnotu true, když byly atributy přístupových práv daného souboru změněny před nn dny (například příkazem chmod). Test -mtime nn vrací hodnotu true, když byl soubor naposledy modifikován před nn dny. Užitečným bude zřejmě test -newer file, který vrací hodnotu true, když byl uvažovaný soubor modifikován později než soubor uvedený jako parametr file. GNU –verze příkazu find také akceptuje testy -anewer a -cnewer, které se chovají podobně jako test -newer, a dále testy -amin, -cmin a -mmin, které pracují s časem uvedeným v minutách.

    V neposlední řadě se musíme zmínit o testu -name pattern. Tento test vrací hodnotu true, pokud jméno souboru vyhovuje šabloně uvedené prostřednictvím parametru pattern. Pro šablonu platí prakticky stejná pravidla jako pro používání pseudoznaků ve jménech souborů, například při používání příkazu ls. Jistě si pamatujete, že příkazový procesor je schopen zvláštním způsobem interpretovat tzv. pseudoznaky (hvězdičku a otazník). Avšak test –name foo* nevrátí tu hodnotu, kterou byste očekávali. Místo toho budete muset použít test -name foo nebo -name "foo*". Dobře si tuto situaci zapamatujte, většina uživatelů používá nesprávný test. Je zde ještě jeden rozdíl oproti příkazu ls - tečky na začátku nejsou interpretovány. Pokud se potřebujete vyrovnat s tímto problémem, použijte test -path pattern, který se o tečky a zpětná lomítka při porovnávání cest nestará.

11.1.5 Akce

    Jak jsme si již řekli, argumenty charakterizující akce slouží k inicializaci nějaké operace. Přesto mezi tyto parametry patří například akce -prune, která nic neaktivuje, pouze realizuje krok dolů ve stromové struktuře adresářů. Většinou je tato akce spjata s parametrem fstype, prostřednictvím kterého se realizuje výběr mezi různými souborovými systémy. Ostatní akce mohou být rozděleny do dvou iirokých kategorií.

    Akce, které něco tisknou. Je zřejmé, že implicitní akcí bude akce -print. Ta v průběhu činnosti programu find tiskne jména souborů, které se právě zpracovávají (ovšem za předpokladu, že ostatní podmínky uvedené v příkazovém řádku vracejí hodnotu true). Akce print má několik variant. První z nich, -fprint file, používá soubor uvedený jako parametr file místo standardního výstupu. Další, -ls, zobrazuje jméno aktuálního souboru jako příkaz ls -dils. Akce -printf format se chová podobně jako funkce printf() v jazyku C (v této variantě lze specifikovat formát výstupu). Totéž realizuje akce -fprintf file, ale do souboru uvedeném prostřednictvím parametru file. Tato akce rovněž vždy vrací hodnotu true.

Akce, které aktivují nějaký příkaz. Jejich syntaxe je poněkud zvláštní, a proto se na ně podívejme podrobněji.

 

-exec command \; Akce -exec spustí příkaz zadaný prostřednictvím parametru command a vrací hodnotu true, pokud má příkaz status ukončení 0. Za příkazem je uvedena dvojice znaků “\;”, protože jinak by příkaz find nebyl schopen rozeznat, kde příkaz command končí (trik s uvedením akce -exec na konec příkazu find není aplikovatelný). Proto se příkaz command ukončuje znakem “;” což je zároveň znak k oddělování příkazů v jazyku příkazového procesoru. Bez znaku “\” by středník byl příkazovým procesorem na základě syntaktické analýzy odstraněn a do příkazu find by se již nedostal. Proto se zde znak “\” musí uvést.
Další věc, kterou si musíte zapamatovat, spočívá ve způsobu specifikace jména aktuálního souboru uvnitř příkazu command. Jméno souboru musí být uvedeno pomocí dvojice složených závorek {}. Některé starší verze programu find vyžadují, aby bylo jméno odděleno netisknutelnými znaky (white spaces), například mezerami. To však není příliš šikovné, proto je ve verzi GNU zavedena konstrukce se složenými závorkami umožňující generovat řetězce. Asi vás napadá otázka, zda musejí být složené závorky uzavřeny do uvozovek. Podle mých zkušeností nemusejí - ani v případě, že použijete příkazový procesor bash, ani v případě, že použijete příkazový procesor tcsh. Proto zůstanou v příkazu find řetězce uvedené ve složených závorkách příkazovým procesorem nedotčeny.
-ok command \; Akce -ok se chová podobně jako akce -exec s tím rozdílem, že pro každý vybraný soubor je uživatel vyzván k potvrzení příkazu (tj. zda se má provést nebo ne). Pokud odpověď začíná písmenem “y” nebo “Y”, příkaz se provede a akce vrátí hodnotu true. Jinak se akce neprovede a vrácená hodnota je false.

11.1.6 Operátory

V příkazu find lze použít spoustu operátorů. Následující seznam je uvádí v pořadí s klesající prioritou.

 

\( expr \) Kulaté závorky mění prioritu operandu. Závorkám musí předcházet znak “\”, protože v příkazovém procesoru mají speciální význam.
! expr
-not expr
Operátory ! a -not mění pravdivostní hodnotu výrazu expr. Je-li hodnota expr true, změní se na false a naopak. Znak “!” nemusí být oddělen obráceným lomítkem nebo uvozovkami, protože je následován netisknutelným znakem (mezerou).
expr1 expr2
expr1 -a expr2
expr1 -and expr2
Všechny tři varianty odpovídají logické operaci AND, přičemž se nejčastěji používá první varianta. Jestliže je první výraz expr1 vyhodnocen jako false, pak se již druhý výraz nevyhodnocuje.
expr1 -o expr2
expr1 -or expr2
Obě varianty odpovídají logické operaci OR. Je-li první výraz expr1 vyhodnocen jako true, pak se již druhý výraz expr2 nevyhodnocuje.
expr1 , expr2 Uvedený operátor má poněkud speciální význam. Oba výrazy expr1 i expr2 se vyhodnotí (samozřejmě se všemi vedlejšími účinky) a hodnota konečného výrazu je nastavena na hodnotu výrazu expr2.

11.1.7 Příklady

    Jak vyplývá z předcházejících seznamů, příkaz find má spoustu parametrů. Existuje však několik často používaných konstrukcí s příkazem find, které stojí za to si zapamatovat. Některé z nich si uvedeme jako příklady.

% find .-name foo\* -print

    První příklad vyhledá všechny soubory, jejichž jména začínají řetězcem foo. Pokud se maj hledat soubory, jejichž jména mají řetězec foo někde uvnitř, pak je vhodné místo foo použít

“*foo*”.

% find /usr/include/ -xtype f -exec grep foobar /dev/null {}\;

    V druhém příkladu se rekurzivně provádí příkaz grep, a to od adresáře /usr/include. V tomto případě se zajímáme o obyčejné soubory a symbolické odkazy, které na obyčejné soubory odkazují. Proto jsme použili test -xtype. V mnoha případech je jednodušší tento test nepoužít, zejména tehdy, kdy jsme si jisti, že žádný binární soubor neobsahuje požadovaný řetězec. A proč jsme použili příkaz /dev/null? Jedná se o trik, který příkaz grep “přinut”? vypsat jméno souboru, pro který nebylo splněno výběrové kritérium. Příkaz grep je aplikován na každý soubor jinak, a proto “nepovažuje” za nezbytné vypisovat jméno souboru. Ale nyní jsou zde dva soubory - aktuální soubor a soubor /dev/null. Jiná možnost spočívá v použití roury a příkazu xargs. Když jsem ji zkusil, zničil jsem si celý souborový systém.

%find / -atime Ctrl+1 -fstype ext2 -name core -exec rm {}\;

    Tento příklad představuje klasickou úlohu pro crontab. Zruší ze souborového systému ext2 všechny soubory s názvem core, které nebyly posledních 24 hodin zpřístupněny. Je možné, že někdo tyto soubory používá v souvislosti s programem gdb k ladění, ale je málo pravděpodobné, že je bude používat po 24 hodinách.

% find /home -xdev -size +500k -ls > piggies

    Další příklad umožňuje zjistit, kdo vlastní soubory větší než 500 kilobajtů a kdo tedy zatěžuje souborový systém. Poznamenejme, že pokud se zajímáme pouze o jeden souborový systém, pak argument -xdev není nutný.

11.1.8 Slovo na závěr

    Mějte na paměti, že příkaz find spotřebuje velmi mnoho času, pokud má provádět operace s každým souborem v celém souborovém systému. Proto je nutné počet operací vhodně optimalizovat, zejména když se na vašem systému pravidelně realizují úlohy pro údržbu prostřednictvím crontab. Jako poučný příklad vezměme následující: Předpokládejme, že chceme zrušit soubory končící na .BAK, přitom chceme změnit přístupová práva všech adresářů na 771 a přístupová práva souborů končících na .sh změnit na 755. Přitom chceme ještě připojit souborový systém NFS na telefonní linku, a v tomto systému nechceme žádné soubory kontrolovat. Proč bychom měli psát tři různé příkazy? Nejefektivněji uvedenou úlohu splníme takto:

% find .\( -fstype nfs -prune \) -o \

\( -type d -a -exec chmod 771 {}\; \) -o \

\( -name "*.BAK" -a -exec /bin/rm {}\; \) -o \

\( -name "*.sh" -a -exec chmod 755 {}\; \)

    Asi se vám bude takový příkaz zdát nesrozumitelný, ale když si jej pozorně prohlédnete, zjistíte, že je logický. Pamatujte si, že příkazy tohoto typu neprovádějí nic jiného, než že vyhodnocují výrazy, jejichž hodnota je buď false, nebo true. Samozřejmě mají vedlejší účinky – ty se realizují tehdy, když příkaz find musí vyhodnotit část obsahující výraz s akcí -exec, což nastane právě tehdy, když je levá strana výrazu vyhodnocena jako pravdivá (true). Když je například právě zpracovávaným souborem adresář, pak se bude realizovat první akce exec a přístupová práva adresáře budou změněna na 771. Ostatní části příkazu budou vynechány. Budete-li takové příkazy aplikovat prakticky, přestanou se vám zdát nesrozumitelné a budete je používat zcela přirozeně.

11.2 Archivační program tar

11.2.1 Úvod

    Tar je obecně použitelný program pro archivaci souborů, který je schopen sloučit (spakovat) velké množství souborů do jediného archivního souboru, přičemž zachovává veýkeré informace o souborech, jako jsou uživatelská práva. Jméno tar je zkratkou “tape archive”, protože tento nástroj byl původně používán pro archivaci na magnetické pásky. Jak však uvidíme, používání příkazu tar není zdaleka omezeno pouze na záložní soubory pro magnetické pásky.

11.2.2 Hlavní funkce

Formát příkazu tar je následující:

tar functionoptions files...

kde function je jednoznaková indikace operace, která se má provést; options je seznam (jednoznakových) voleb pro tuto operaci a files je seznam souborů, jež se mají spakovat nebo rozpakovat. (Všimněte si, že argument function není oddělen od options mezerou.) Parametr function může být:

 

c vytvoření nového archivního souboru
x extrakci souborů z archivního souboru
t výpis obsahu archivního souboru
r přidání souborů na konec archivního souboru
u aktualizaci souborů, které jsou novější než soubory v archivním souboru
d porovnání souborů v archivním souboru se soubory v souborovém systému

Nejčastěji budete používat parametr c, x a t; ostatní budete používat jen zřídka.

11.2.3 Volby

Nejčastěji používané volby options jsou tyto:

 

v tisk podrobné informace v průběhu pakování a rozpakování
k zachování existujících souborů při rozpakování, tj. žádný existující soubor nebude přepsán souborem z archivního souboru
f filename ... pro specifikaci jména archivního souboru

11.2.4 Příklady

    Ačkoliv se syntaxe příkazu tar zdá být na první pohled složitá, je jeho praktické použití velmi jednoduché. Předpokládejme, že máme adresář mt obsahující následující soubory:

rutabaga% ls -l mt

-rw-r--r-- 1 root root 24 Sep 21 1993 Makefile

-rw-r--r-- 1 root root 847 Sep 21 1993 README

-rw-r--r-- 1 root root 9220 Nov 16 19:03 mt

-rwxr-xr-x 1 root root 2775 Aug 7 1993 mt.1

-rw-r--r-- 1 root root 6421 Aug 7 1993 mt.c

-rw-r--r-- 1 root root 3948 Nov 16 19:02 mt.o

-rw-r--r-- 1 root root 11204 Sep 5 1993 st_info.txt

Nyní chceme spakovat pomocí příkazu tar obsah tohoto adresáře do jediného archivního souboru. Použijeme tedy příkaz:

tar cf mt.tar mt

    Prvním argumentem v příkazu tar je operace (zde c pro vytvoření) následovaná volbou options, kde jsme použili f mt.tar a specifikovali tak jméno archivního souboru mt.tar. Jako poslední je uveden seznam souborů - pokud se místo seznamu uvede název adresáře, tar spakuje všechny soubory v tomto adresáři.

    Poznamenejme, že prvním argumentem musí být písmeno, označující operaci, následované seznamem voleb “options”. Proto není důvod dávat před první argument pomlčku, jak to vyžaduje většina systémů Unix. Příkaz tar v systému Linux však tuto pomlčku připouští, proto by mohl mít posledně uvedený příklad tvar:

tar -cf mt.tar mt

    V některých verzích musí být typ operace (jako je c, t, nebo x) na prvním místě, v jiných verzích na pořadí písmen nezáleží. Jistý přehled o průběhu pakování (nebo rozpakování) získáte prostřednictvím volby v - pak se bude každý soubor ukládaný do archivního souboru vypisovat na obrazovce. Například:

rutabaga% tar cvf mt.tar mt

mt/

mt/st_info.txt

mt/README

mt/mt.1

mt/Makefile

mt/mt.c

mt/mt.o

mt/mt

Použijete-li volbu v vícekrát, zobrazovaná informace bude podrobnější:

rutabaga% tar cvvf mt.tar mt

drwxr-xr-x root/root 0 Nov 16 19:03 1994 mt/

-rw-r--r-- root/root 11204 Sep 5 13:10 1993 mt/st_info.txt

-rw-r--r-- root/root 847 Sep 21 16:37 1993 mt/README

-rwxr-xr-x root/root 2775 Aug 7 05:50 1993 mt/mt.1

-rw-r--r-- root/root 24 Sep 21 16:03 1993 mt/Makefile

-rw-r--r-- root/root 6421 Aug 7 09:50 1993 mt/mt.c

-rw-r--r-- root/root 3948 Nov 16 19:02 1994 mt/mt.o

-rw-r--r-- root/root 9220 Nov 16 19:03 1994 mt/mt

    Tyto podrobné informace jsou důležité zejména tehdy, když chcete zkontrolovat, zda tar realizuje pakování dle vašich představ. U některých verzí programu tar musí být volba f uvedena jako poslední. Je to z toho důvodu, že se za volbou f předpokládá jméno souboru. Pokud neuvedete volbu f, předpokládá tar (z historických důvodů), že má použít zařízení /dev/rmt0, což je první magnetopásková jednotka.

Nyní můžeme soubor mt.tar předat někomu jinému a ten si jej může rozpakovat na svém počítači. K rozpakování by měl použít následující příkaz:

tar xvf mt.tar

    Tento příkaz vytvoří adresář mt a umístí do něj všechny soubory, které jsme dříve uvedli s týmiž přístupovými právy jako v původním systému. Nové soubory budou vlastněny uživatelem, který provedl příkaz tar xvf - pokud ovšem nepoužijete tento příkaz jako root (pak je původní vlastník zachován). Parametr x zajistí rozpakování souborů a volba v opět zobrazí soubory, které se ukládají na disk:

courgette% tar xvf mmt.tar

mt/

mt/st_info.txt

mt/README

mt/mt.1

mt/Makefile

mt/mt.c

mt/mt.o

mt/mt

    Všimněte si, že tar zachoval cestu každého souboru relativní k poloze v původní struktuře adresářů. To znamená, že když jsme vytvářeli archivní soubor pomocí příkazu tar cf mt.tar mt, jediný soubor, který jsme specifikovali místo seznamu souborů, byl adresář mt obsahující soubory. Proto tar uložil do archivního souboru samotný adresář a soubory, které se v něm nacházely. Při rozpakování se napřed vytvořil adresář mt a pak do něj byly uloženy soubory - tedy přesně opačný proces, než jaký probíhal při vytváření archivního souboru. tar implicitně rozpakuje všechny soubory relativně k pracovnímu adresáři, v němž jej spustíte.

Pokud se například pokusíte spakovat obsah adresáře /bin příkazem:

tar cvf bin.tar /bin

dostanete varovné hlášení:

tar: Removing leading / from absolute path names in the archive.

    To znamená, že soubory jsou ukládány v archivním souboru uvnitř adresáře /bin. Když tento soubor rozpakujete, adresář /bin bude vytvořen jako podadresář vašeho pracovního adresáře, v němž spouštíte tar - ne jako absolutní adresář /bin. Toto je velmi důležitý mechanismus, který byl vymyýšen za účelem ochrany před fatálními chybami při rozpakování pomocí příkazu tar. Jinak byste, podle předchozího příkladu, mohli přepsat soubory v adresáři /bin, a tak zničit systém.

    Pokud byste však opravdu chtěli rozpakovat takový archivní soubor do adresáře /bin, museli byste mít jako pracovní adresář nastaven /. Všie uvedený mechanismus můžete potlačit pomocí volby p, ale nedoporučuje se to. Jiný způsob, jak vytvořit soubor mt.tar, spočívá v tom, že se přepnete do adresáře mt pomocí příkazu cd a zadáte příkaz:

tar cvf mt.tar *

    Potom ovšem nebude podadresář mt ukládán do archivního souboru a při rozpakování budou soubory ukládány přímo do vašeho pracovního adresáře. Proto doporučujeme vždy pakovat soubory tak, aby archivní soubor obsahoval podadresář, jak jsme ukázali pomocí příkazu tar cvf mt.tar mt. Pak se vždy před rozpakováním vytvoří adresář pro uložení souborů a nemůže se stát, že přepíšete soubory ve svém pracovním adresáři. Navíc zbavíte osobu, která provádí rozpakování, starostí s vytvářením adresáře pro ukládání souborů a ušetříte jí dost času. Samozřejmě existuje mnoho situací, při nichž nebude vhodné doporučený postup dodržovat, ale všeobecně se takový postup považuje za jakousi etiketu při práci s programem tar.

    Při vytváření archivních souborů můžete uvést seznam souborů nebo adresářů, které se mají do archivního souboru uložit. V prvním příkladu jsme použili příkaz tar pro jediný adresář a ukázali jsme použití hvězdičky, kterou příkazový procesor rozšíří na seznam všech souborů v pracovním adresáři. Před rozpakováním archivního souboru pomocí příkazu tar je vhodné se podívat, co je jeho obsahem. Tak se například dozvíte, zda budete muset vytvořit adresář pro uložení souborů vlastními silami, nebo bude vytvořen automaticky. K prohlížení obsahu archivního souboru použijte příkaz:

tar tvf tarfile

Ten zobrazí obsah archivního souboru tarfile. Poznamenejme, že pokud použijete funkci t, stačí uvést jednu volbu v a obdržíte podrobnou informaci o obsahu archivního souboru:

courgette% tar tvf mt.tar mt

drwxr-xr-x root/root 0 Nov 16 19:03 1994 mt/

-rw-r--r-- root/root 11204 Sep 5 13:10 1993 mt/st_info.txt

-rw-r--r-- root/root 847 Sep 21 16:37 1993 mt/README

-rwxr-xr-x root/root 2775 Aug 7 05:50 1993 mt/mt.1

-rw-r--r-- root/root 24 Sep 21 16:03 1993 mt/Makefile

-rw-r--r-- root/root 6421 Aug 7 09:50 1993 mt/mt.c

-rw-r--r-- root/root 3948 Nov 16 19:02 1994 mt/mt.o

-rw-r--r-- root/root 9220 Nov 16 19:03 1994 mt/mt

    Žádné rozpakování v tomto případě neproběhne, ale pouze se zobrazí informace o obsahu archivního souboru. Zde vidíme, že jména souborů jsou doplněna jménem adresáře mt, a proto při rozpakování bude tento adresář nejdříve vytvořen a pak teprve do něj budou ukládány soubory. Příkaz tar můžete rovněž použít k extrakci jednotlivých souborů z archivního souboru. Potom použijte příkaz ve tvaru:

tar xvf tarfile files

kde files je seznam souborů, které se mají rozpakovat. Jak jsme si již ukázali, pokud neuvedeme žádný seznam, tar rozpakuje všechny soubory z archivního souboru.

    Jestliže specifikujete soubory, které se mají rozpakovat, musíte uvést jejich plná jména včetně cesty tak, jak jsou uvedena v archivním souboru. Chceme-li například rozpakovat soubor mt.c z všie uvedeného archivního souboru mt.tar, použijeme následující příkaz:

tar xvf mt.tar mt/mt.c

který nejdříve vytvoří podadresář mt a do něj pak umístí soubor mt.c. Program tar má mnohem více možností, než které jsme zde uvedli. Ty, o nichž jsme se zde zmínili, budete zřejmě používat nejčastěji. Verze GNU implementovaná operačnímu systému Linux má řadu přípon a představuje ideální nástroj pro pořizování záložních kopií. Více informací naleznete v manuálové stránce k příkazu tar.

11.2.5 Jak používat program tar spolu s programem gzip

    Program tar neprovádí při ukládání dat do archivního souboru žádnou komprimaci. Jestliže vytvoříte soubor tar ze tří souborů o velikosti 200 KB, pak výsledný soubor bude mít velikost 600 KB. Proto patří k běžné praxi komprimovat soubory tar pomocí programu gzip (nebo starším programem compress). Komprimovaný soubor tar můžete vytvořit pomocí následujících příkazů:

tar cvf tarfile files...

gzip -9 tarfile

Provedení takových příkazů je však těžkopádné a vyžaduje, abyste měli na disku dostatek místa pro nekomprimovaný soubor tar, než spustíte gzip.

    Mnohem efektivnější způsob spočívá v tom, že se využije možnost programu tar zapisovat archivní soubor do standardního výstupu. Pokud použijete místo jména archivního souboru pomlčku (-), pak bude tar číst data ze standardního vstupu nebo zapisovat do standardního výstupu. K vytvoření komprimovaného souboru tar tedy můžeme použít příkaz:

tar cvf - files... | gzip -9 > tarfile.tar.gz

    Zde vytváří tar archivní soubor ze souborů uvedených v seznamu files, zapisuje jej do standardního výstupu; gzip čte data ze standardního vstupu, komprimuje je a zapisuje do svého standardního výstupu. Nakonec jsme přesměrovali komprimovaný soubor tar do tarfile.tar.gz. Podobně bychom mohli k rozpakování takového souboru použít příkaz:

    gunzip -9c tarfile.tar.gz | tar xvf

Zde gunzip provede dekomprimaci uvedeného archivního souboru a zapisuje výsledek do standardního výstupu sloužícího jako standardní vstup pro program tar, jenž soubory rozpakuje a ukládá. Není práce v systému Unix zábavná? Samozřejmě, že jsou oba všie uvedenépříkazy poněkud těžkopádné. Naštěstí GNU-verze programu tar má možnost uvést volbu z, která zajistí automatické vytváření nebo rozpakování komprimovaných archivních souborů tar. (Diskusi o použití volby z jsme úmyslně zařadili až na toto místo, abyste si uvědomili její výhody.) K vytvoření a rozpakování archivních souborů máte tedy možnost používat následující příkazy:

tar cvzf tarfile.tar.gz files...

a

tar xvzf tarfile.tar.gz

    Poznamenejme, že byste měli soubory vytvořené tímto způsobem označovat pomocí přípony .tar.gz, aby byl zřejmý jejich formát. Volba funguje i ve spojení s dalšími parametry, jako je například t. Možnost používat volbu z podporuje pouze GNU-verze programu tar. Jestliže používáte tar na jiných systémech Unix, musíte pro realizaci stejného úkolu zadávat delší příkazy, jak jsme uvedli dříve. Téměř všechny verze operačního systému Linux používají verzi GNU.

    Nyní využijeme svých znalostí a napíšeme krátké skripty pro příkazový procesor, které vám mohou sloužit jako návod pro vytváření a rozpakování souborů tar. V příkazovém procesoru bash doplňte následující řádky do souboru .bashrc:

tarc () {tar czvf $1.tar.gz $1 }

tarx () {tar xzvf $1 }

tart () {tar tzvf $1 }

Budete-li nyní chtít vytvořit komprimovaný archivní soubor obsahující soubory z jednoho adresáře, stačí zadat příkaz:

tarc directory

    Výsledný archivní soubor bude mít název directory.tar.gz. (Přesvědčte se, že jste neuvedli před jménem adresáře lomítka (/) - jinak bude archivní soubor vytvořen jako .tar.gz uvnitř daného adresáře.) K zobrazení obsahu archivního souboru stačí zadat příkaz

tart file.tar.gz

a k jeho rozpakování příkaz

tarx file.tar.gz

11.2.6 Triky při používání programu tar

    Protože tar ukládá do archivního souboru informace o vlastnictví souborů, přístupových právech, adresářové struktuře i symbolických odkazech, velmi dobře se hodí ke kopírování nebo přesouvání celých adresářových stromů z jednoho místa na druhé v rámci jednoho systému (a dokonce i mezi systémy, jak uvidíte). Použijete-li syntaxi s pomlčkou (-), budete zapisovat výsledný soubor do standardního výstupu, který může být čten jako standardní vstup a rozpakován kdekoliv.

    Předpokládejme například, že máme adresář obsahující dva podadresáře: fromstuff a to-stuff. Adresář from-stuff obsahuje celý strom dalších podadresářů s mnoha soubory, symbolickými odkazy atd. a bylo by velmi obtížné zkopírovat jej pomocí příkazu cp. Ke zkopírování celého adresáře from-stuff do adresáře to-stuff však můžeme použít následující příkazy:

cd from-stuff

tar cf - .| (cd ../to-stuff; tar xvf -)

    Velice jednoduché a elegantní! Začínáme v adresáři from-stuff, kde vytvoříme soubor tar obsahující celý adresář, a zapíšeme jej do standardního výstupu. Tento výstup pak čte podřízený příkazový procesor (příkazy uvedené v závorkách), který se nejdříve přepne do adresáře ../to-stuff a pak spustí příkaz tar xvf, jenž čte ze standardního vstupu. Přitom se žádný archivní soubor tar neukládá na disk - data jsou přímo posílána z jednoho procesu tar do druhého. Druhý proces tar používá volbu v pro zobrazení informací o každém souboru, který se ukládá, a vy můžete kontrolovat, zda kopírování obsahu adresářů probíhá správně.

    Pomocí tohoto “triku” můžete ve skutečnosti přenášet celé adresáře mezi jednotlivými systémy - stačí vložit vhodný příkaz rsh mezi příkazy uzavřené v závorkách. Pak vzdálený příkazový procesor spustí tar, který bude číst archivní soubor jako standardní vstup. (Poznamenejme, že verze GNU příkazu tar má možnost automaticky číst nebo zapisovat soubory tar z/do jiných počítačů v síti; informace najdete v příslušné manuálové stránce.)

11.3 Program dd

    Existuje jakási legenda, podle které v ranných dobách vývoje operačního systému Unix potřebovali programátoři program pro binární kopírování dat mezi jednotlivými zařízeními. Protože velmi spěchali, “vypůjčili” si syntaxi příkazu používanou v operačním systému na počítačích IBAltCtrl+360 a později vyvinuli rozhraní konzistentní s ostatními příkazy operačního systému Unix. Nevím, zda je tato legenda pravdivá, ale pěkně se vypráví.

11.3.1 Volby

    Přes svůj legendou opředený původ není program dd úplně jiný než ostatní příkazy operačního systému Unix. Ve skutečnosti představuje filtr, který implicitně čte data ze standardního vstupu a zapisuje je na standardní výstup. Pokud zadáte na terminálu pouze příkaz dd, pak bude program dd tiše očekávat vstup z klávesnice.

Syntaxe příkazu dd je následující:

dd [if=file] [of=file] [ibs=bytes] [obs=bytes]

[bs=bytes] [cbs=bytes] [skip=blocks] [seek=blocks]

[count=blocks] [conv={ascii, ebcdic, ibm, block,

unblock, lcase, ucase, swab, noerror, notrunc, sync}]

    Všechny volby mají tvar option=value. Před a za znakem “=” se nesmí objevit mezera, což je nepříjemné, protože v takové situaci neprovede příkazový procesor doplnění jména souboru, pokud se uvedou pseudoznaky. Verze příkazového procesoru bash v operačním systému Linux je však dostatečně inteligentní, proto nemusíte mít obavy. Všechny všie uvedené číselné hodnoty (bytes a blocks) mohou být následovány multiplikativní konstantou. Pro tyto konstanty lze použít následující zkratky: b pro bloky (multiplikativní konstanta 512), k prokilobajty (multiplikativní konstanta 1024), w pro slova ( multiplikativní konstanta 2) a prostřednictvím xm se číselná hodnota násobí konstantou m. Význam voleb příkazu dd je popsán v následujícím seznamu.

if=filein a of=fileout jsou volby specifikující jméno vstupního a výstupního souboru.

    Výstupní soubor je zkrácen na velikost danou volbou seek. Pokud není klíčové slovo seek uvedeno, pak je hodnota seek rovna nule (soubor je před provedením operace zrušen). Volba notrunc (viz dále) však může toto implicitní chování příkazu dd změnit.

    Dříve či později se setkáte s případem, kdy budete chtít pod operačním systémem Linux vytvořit svoji první disketu. Jak zapsat data na disketu bez souborového systému MS-DOS? Řešení je jednoduché:

% dd if=disk.img of=/dev/fd0 obs=18k count=80

    V uvedeném příkladu jsem se rozhodl nepoužít volbu ibs, protože nevím jaká je optimální volba pro velikost bloku na pevném disku. Nemůže však uýkodit, když se místo volby obs použije volba bs - pak je proces kopírování dokonce rychlejší. Všimněte si nastavení počtu sektorů pro zápis (18 kilobajtů je velikost sektoru, proto je hodnota count nastavena na 80). Pro disketovou jednotku se v operačním systému Linux používá jméno zařízení /dev/fd0.

    Další užitečné použití příkazu dd je v oblasti zálohování, zejména při zapojení počítače do sítě. Předpokládejme, že máte počítač alfa a že na počítači beta je magnetopásková jednotka /dev/rst0 obsahující soubor, který chcete zkopírovat. Dále předpokládejme, že máte stejná přístupová práva na obou počítačích a že na pevném disku počítače beta není dostatek místa pro kopii uvažovaného souboru. Pak můžete použít příkaz:

% rsh beta 'dd if=/dev/rst0 ibs=8k obs=20k' | tar xvBf

    Celou operaci takto realizujete “na jeden průchod”. Zajisté jste si všimli, že se v příkazu využila schopnost příkazového procesoru číst data z magnetopáskové jednotky. Velikosti vstupních a výstupních bloků jsou nastaveny na implicitní hodnoty, tedy 8 kilobajtů pro čtení a 20 kilobajtů pro zápis do sítě ethernet.

Poznámka na závěr: zapomněl jsem říci, že označení příkazu dd je zkratkou pro výraz “data duplicator”.

Previous Content Next Up