25Kapitola

Bash 25: Poslední opakování

bash.jpg

Tak a je tu poslední díl seriálu o textovém příkazovém interpretru Bash. Podobně jako minule si ukážeme dříve probraná témata na příkladu reálného skriptu. Tentokrát jsem vybral systémový skript používaný programem Init.

Spouštění systému

Nebudu se zde podrobně zabývat problematikou spouštění operačního systému. Pro naše potřeby postačí vědět, že po zapnutí počítače naběhne BIOS, ten zavolá správce spouštění (boot manager) a v něm si vybereme požadovaný operační systém. V případě Linuxu se načte jádro, osahá si hardware a předá činnost hlavnímu procesu – programu Init.

Init se stará o spouštění všech dalších programů. Nejdříve to jsou různé služby běžící na pozadí (démoni), nakonec potom správce přihlášení pro textové nebo grafické prostředí. Nás budou zajímat právě démoni. Ty totiž Init nespouští přímo, ale pomocí skriptů uložených v adresáři /etc/init.d/.

Ukážeme si, jak pracuje spouštěcí skript pro démona crond. Ten se stará o opakované provádění nastavených operací v určeném čase (např. jednou denně nebo týdně). Tento skript najdete ve svém systému pravděpodobně pod jménem /etc/init.d/crond.

Stáhněte si ukázkový skript.

Rozbor skriptu

Příklad skriptu /etc/init.d/crond z Fedora Core 6 je uveden v rámečku. Pro usnadnění orientace má očíslované řádky, takže jej nebudu kouskovat přímo do textu, ale podle těchto čísel se na jeho jednotlivé části odvolávat.

První řádek určuje, že skript má být proveden Bashem. Druhý řádek volá skript /etc/init.d/functions, pomocí něhož se nadefinují některé funkce, které budou dále použity (viz 23. díl). Podobně řádek 3 volá skript, který nastaví některé proměnné (viz 4. díl) pro konfiguraci Cronu.

Čtvrtý řádek definuje proměnnou t a využívá k tomu expanzi parametrů (viz 21. díl). Pokud je (např. ze souboru /etc/sysconfig/crond) nastavena proměnná CRON_VALIDATE_MAILRCPTS, převezme t její hodnotu. Pokud tomu tak není, vloží se do t řetězec UNSET (anglicky nenastaveno).

V pátém řádku se nachází jednoduchá podmínka s testem (viz 10. díl). Pokud se obsah proměnné t nerovná řetězci UNSET, bude proměnná CRON_VALIDATE_MAILRCPTS nastavena na hodnotu t a zpřístupněna ostatním procesům pomocí export. Šestý řádek prostě nastavuje proměnné prog hodnotu crond.

Na řádcích 7 až 22 se nachází definice funkce (viz 23. díl) start(), tj. posloupnost příkazů prováděných při spouštění Cronu. Nejprve (řádek 8) se vypíše hláška Starting crond:, pak (řádky 9-16) následuje podmínka (viz 11. díl). Ta se provede jen za předpokladu, že existuje soubor /var/lock/subsys/crond (viz 10. díl).

Pokud se podmínka vykonává, dostáváme se k další, která leží na řádcích 10 až 15. Hodnotí, zda existuje soubor /var/run/crond.pid (vytvářený při spouštění démona). Pokud ano, potom ještě (&&), zda existuje v adresáři /proc/ soubor (nebo adresář), jehož jméno je stejné jako obsah souboru /var/run/crond.pid. K tomu bylo použito mechanismu nahrazování příkazů (viz 20. díl). Tím si skript ověří, zda už náhodou nějaký Cron neběží.

 

Pokud Cron již běží, vypíše se o tom varovná hláška (řádek 11). Dál se provede funkce failure (anglicky selhání, řádek 12) definovaná ve skriptu /etc/init.d/functions, která zapíše vzniklý problém do logu. V řádku 13 se pomocí echo odřádkuje a 14. řádek nastaví návratovou hodnotu na 1 (viz 10. díl).

V řádku 17 dochází konečně k samotnému spuštění Cronu. Slouží k tomu funkce (viz 23. díl) daemon definovaná v /etc/init.d/functions. Jako poziční parametry (viz 17. díl) přijímá jméno spouštěného démonu a seznam jeho parametrů, v našem případě obsah proměnné $CRONDARGS definované v konfiguračním souboru /etc/sysconfig/crond.

V řádku 18 nabývá proměnná RETVAL hodnotu posledního návratového kódu ($? - viz 19. díl). Echo na řádku 19 odřádkuje a dostáváme se k podmínce (viz 10. díl) na řádku 20. Ta v případě, že RETVAL má hodnotu 0, vytvoří prázdný soubor (zámek) /var/lock/subsys/crond. Definice funkce start() (viz 23. díl) končí předáním návratové hodnoty RETVAL.

Na řádcích 23 až 36 je definována funkce stop(), která se funkci start() dosti podobá. Na řádku 24 se vypíše hlášení o zastavování Cronu. Řádky 25 až 30 jsou podmínkou prováděnou v případě, že neexistuje soubor (zámek) /var/lock/subsys/crond. Tehdy se vypíší varovné hlášky, že Cron nelze zastavit, když neběží, a vrátí se chybová hodnota 1.

Řádek 31 volá další funkci definovanou skriptem /etc/init.d/functions. Killproc se postará o korektní zastavení zadaného démonu, v našem případě crond. Pak následuje přiřazení hodnoty návratového kódu proměnné RETVAL. Pokud je to 0 (bez chyby), tak se v řádku 34 odstraní soubor (zámek) /var/lock/subsys/crond.

Funkce rhstatus() definovaná na řádcích 37 až 39 volá pouze funkci status definovanou ve skriptu /etc/init.d/functions. Ta jen vypíše, zda zadaný démon (v našem případě samozřejmě crond) běží. Na řádcích 40 až 43 najdeme definici funkce restart(). Je velmi prostá, neboť prostě vykoná posloupnost dříve definovaných funkcí stop() a start().

Řádky 44 až 50 ukrývají obsah funkce reload(). Ta, na rozdíl od restart(), Cron neukončí, ale pouze jej donutí znovu načíst konfigurační soubory. Nejprve o tom vypíše hlášku v řádku 45. Potom zavolá funkci killproc, která procesu jménem crond pošle signál (viz 2. díl) -HUP, což je ekvivalent kill -1 (viz man 7 signal). Pak už následuje jen definice návratového kódu.

Tím jsme ukončili definici funkcí ve skriptu a dostáváme se k jeho hlavní části (která se např. v jazyce C označuje jako Main). Ta se rozkládá na řádcích 51 až 73 a je tvořena jedinou konstrukcí case (viz 15. díl).

Jednotlivé části case budou provedeny v závislosti na hodnotě prvního pozičního parametru ($1 - viz 17. díl). Záleží tedy na tom, s jakým parametrem byl námi zde analyzovaný skript /etc/init.d/crond spuštěn. Jak se asi dovtípíte, v závislosti na tom může sloužit nejen ke spouštění, ale i zastavování a dalším způsobům ovládání Cronu.

Pokud byl skript volán s parametrem start (52. řádek), bude provedena funkce start() (53. řádek) a sekci ukončuje dvojice středníků (54. řádek). Podobně následují situace pro hodnoty pozičního parametru stop, restart, reload a status.

Na řádku 68 je složená podmínka (viz 10. díl) pro parametr condrestart. Pokud existuje soubor (zámek) /var/lock/subsys/crond, provede se restart. Pokud ne (||), bude vrácen nulový návratový kód, k čemuž slouží nicnedělající interní příkaz dvojtečka (:).

Před uzavřením konstrukce case zbývá vypořádat se s případy, kdy byl skript spuštěn s jiným parametrem, než jaké jsme dosud jmenovali. K tomu slouží sekce v řádcích 70 až 72 uvozená hvězdičkou. V tom případě se vypíše krátká informace o použití (anglicky Usage) se jménem skriptu ($0 - viz 17. díl) a seznamem přípustných parametrů a skript je zakončen návratovým kódem 1.

A to je opravdu vše. Pravidelným čtenářům děkuji za přízeň. Všem zájemcům o Bash přeji mnoho úspěchů při používání tohoto mocného nástroje a tvorbě vlastních skriptů.