Čas je důležitý nejen proto, abychom jej mohli sledovat na monitoru a nemuseli stále hledat hodinky. Počítač nám také může některé věci v určený čas sám připomenout nebo spustit zadaný příkaz. Dále se čas používá k označení okamžiku vytvoření nebo posledního přístupu k souboru, pro záznamy v logu a pro mnoho dalších důležitých věcí.
Nejjednodušší nastavení je samozřejmě nechat systém vždy při startu vyčíst čas z hardwarových hodin počítače. Dále lze čas měnit ručně. Maximální přesnost a automatizaci přináší synchronizace po síti. My si proto ukážeme využití protokolů time a NTP pro tento účel. Přesně seřízené minuty a sekundy by ovšem nebyly k ničemu, kdyby systém nevěděl, ve které se nachází časové zóně. Proto se budu věnovat i tomuto tématu.
Hardwarové hodiny
Většina počítačů obsahuje baterií zálohované interní hodiny. To umožňuje, aby čas běžel i po vypnutí počítače. Po dalším zapnutí si operační systém vyčte potřebné údaje z interních hodin. Přesnost těchto hodin však nemusí být nejvyšší a je ovlivněna mnoha faktory. Operační systém si v průběhu svého běhu počítá čas sám. Při řádném ukončování své práce jej zase zapíše do interních hodin. Obsluhu těchto hardwarových hodin (též hodiny reálného času, RTC, BIOS či CMOS) zajistíme následujícími příkazy:
hwclock -r - čte nastavení interních hodin; hwclock -s - nastaví systémové hodiny podle interních hodin; hwclock -w - nastaví interní hodiny podle systémových hodin; hwclock --set --date="2004-10-20 11:22:33" - nastaví interní hodiny na 11:22:33, 20. října 2004; hwclock --set --date="7/22/2005 21:24:05" - nastaví interní hodiny na 21:24:05, 22. července 2005.
Program hwclock bývá umístěn v adresáři /usr/sbin, který má v cestě nastaven většinou jen uživatel root. Proto, pokud budete chtít hwclock spouštět jako běžný uživatel, musíte zadat celou cestu (např. /usr/sbin/hwclock -r). Operace, při kterých dochází ke změně systémového nebo interního času, však může provádět pouze superuživatel.
Systémový čas
Tímto termínem označujeme čas, který si obhospodařuje jádro operačního systému. Měří jej počtem sekund uplynulých od 1. 1. 1970 00:00:00 do současnosti. Zobrazit či nastavit jej však můžeme v mnohem lidštější podobě. Tento čas využívají také všechny v systému běžící aplikace. Jak systémový čas nastavit z interních hodin, jsme si již předvedli. Nyní několik příkladů, jak jej číst a nastavit ručně:
date - vypíše aktuální systémový čas; date -s '2004-10-20 11:22:33' - nastaví systémový čas na 11:22:33, 20. října 2004; date -s '7/22/2005 22:22:05' - nastaví systémový čas na 22:22:05, 22. července 2005.
Program date umožňuje širokou škálu formátů zobrazení data a času. Využívá k tomu sadu zástupných znaků, z níž vybíráme v rámečku. Tyto speciální znaky můžeme doplňovat znaky zcela běžnými. Několik příkladů s výsledky:
date '+%H:%M.%S' - 23:03.34 date '+%s' - 1122073464 date '+%H:%M.%S, %A %d. %b %Y' - 23:08.08, Pátek 22. čec 2005
Zástupné znaky pro date
Zástupné znaky času %H - hodina (00..23) %I - hodina (01..12) %k - hodina (0..23) %l - hodina (1..12) %M - minuta (00..59) %r - čas ve dvanáctihodinovém cyklu (hh:mm:ss [AP]M) %s - počet sekund od 1. ledna 1970 00:00:00 UTC %S - sekundy (00..61) %T - čas ve čtyřiadvacetihodinovém cyklu (hh:mm:ss) Zástupné znaky data %a - zkratka dne v týdnu podle locales (Po..Ne) %A - plné jméno dne v týdnu (Pondělí..Neděle) %b - zkratka měsíce podle locales (Led..Pro) %B - plné jméno měsíce (leden..prosinec) %d - den v měsíci (01..31) %D - datum ve tvaru mm/dd/rr %j - den v roce (001..366) %m - měsíc (01..12) %U - číslo týdne s nedělí jako prvním dnem týdne (00..53) %w - den v týdnu (0..6), 0 znamená neděle %W - číslo týdne s pondělím jako prvním dnem v týdnu (00..53) %y - poslední dvojčíslí roku (00..99) %Y - rok (1970...)
Nastavení po síti - rdate
Program rdate je klientem síťového protokolu time, tedy něco podobného jako internetový prohlížeč v rámci protokolu HTTP. Protokol time je definován dokumentem RFC 868 z roku 1983 a je relativně jednoduchý. Dokáže používat jak pakety typu TCP, tak i UDP - oba na portu 37. Asi nejobtížnější úkol je tak najít si veřejný server, který tuto službu (ještě) nabízí. Program rdate bývá standardní součástí linuxových distribucí, stačí tedy zadat např.:
rdate time.ien.it - zobrazí čas získaný od vzdáleného serveru pomocí TCP; rdate -u tick.greyware.com - zobrazí čas získaný od vzdáleného serveru pomocí UDP; rdate -s ntps1-2.uni-erlangen.de - nastaví systémový čas podle údajů získaných od vzdáleného serveru.
Pro nastavení systémového času je samozřejmě nutné mít práva superuživatele. Nejlepší je využívat servery, ke kterým mají naše pakety nejrychlejší cestu. V tom by vám měl poradit správce místní sítě nebo poskytovatel připojení k internetu. Synchronizaci můžeme provádět ručně nebo tuto činnost zautomatizovat. Toho lze dosáhnout např. zařazením do startovacích nebo přihlašovacích skriptů. Elegantnější je ovšem pravidelná činnost zajišťovaná démonem cron, který si popíšeme dále.
Nastavení po síti - NTP
Protokol NTP (Network Time Protocol) je mnohem propracovanější metodou synchronizace času po síti. Existuje již ve čtyřech verzích, které jsou definovány v RFC 1059 (v1), RFC 1119 (v2), RFC 1305 (v3) a RFC 2030 (v4). Posledně zmíněná je díky zjednodušením, která přinesla, označována též SNTP (Simple Network Time Protocol).
Převratnou vlastností NTP je stromová struktura časových serverů. Servery nejvyšší úrovně (stratum-1) jsou propojeny se zařízením přesného času (atomové, GPS či rádiové hodiny). Serverů druhé úrovně, které se s nimi synchronizují, je mnohem více. Běžní uživatelé by totiž servery stratum-1 neměli vůbec obtěžovat a využívat jen služeb serverů na úrovních nižších. Těch může být teoreticky až 15.
Narozdíl od serverů využívajících time protocol existují v případě NTP veřejné seznamy takovýchto serverů. Pro ČR na úrovni stratum-2 najdeme např. ntp.cgi.cz, ntp.globe.cz, ntp.karpo.cz, ntp1.contactel.cz, ntp2.contactel.cz.
V balíčku programů pro práci s NTP najdeme mimo jiné též ntpdate. Funkčností je podobný dříve popsanému rdate. Prostě čte časové údaje ze vzdáleného serveru, případně podle něj nastavuje lokální systémový čas. Např. takto:
ntpdate -q ntp.karpo.cz - zobrazí čas získaný od vzdáleného NTP serveru; ntpdate ntp.globe.cz - nastaví systémový čas podle údajů získaných od vzdáleného NTP serveru.
Jinak zde platí poznámky podobné jako u rdate. Jen pokud chce ke čtení vzdáleného času využít ntpdate neprivilegovaný uživatel, musí zadat celou cestu k programu (např. /usr/sbin/ntpdate -q ntp.cgi.cz). Celý ntpdate je ale spíše berlička.
Hlavní síla NTP spočívá ve schopnosti běžet na pozadí a synchronizovat čas průběžně. K tomu slouží program ntpd. Ten lze v distribucích většinou spouštět jako standardní službu (daemon) - např. /etc/init.d/ntpd start. Nejprve je však dobré jej nakonfigurovat. Ke konfiguraci lokálního NTP serveru slouží soubor /etc/ntp.conf, který může vypadat např. následovně:
# /etc/ntp.conf server ntp.cgi.cz server ntp.globe.cz server ntp.karpo.cz driftfile /etc/ntp/drift broadcastdelay 0.008 authenticate no
Nyní stačí server spustit, případně jej přidat do seznamu služeb spouštěných automaticky v příslušných úrovních běhu systému. Toho můžeme docílit v distribucích odvozených z Red Hat např. pomocí chkconfig --level 2345 ntpd on. Dáváte-li přednost grafice, zkuste system-config-services (v Mandrivě /usr/sbin/drakclock).
Činnost serveru můžete průběžně sledovat. Jednoduchým nástrojem, k tomu určeným, je ntpstat. Zpočátku může vypisovat hlášení typu "unsynchronised, time server re-starting, polling server every 16 s". Až však prvotní synchronizace proběhne (což může trvat i přes 10 minut), bude mít hlášení spíše podobu: "synchronised to NTP server (81.95.96.3) at stratum 3, time correct to within 22 ms, polling server every 64 s".
Vedle ntpstat existuje ještě několik sofistikovanějších nástrojů pro ovládání NTP serveru ntpd. Jmenujme interaktivní ntpdc a ntpq. Případné zájemce odkáži na manuálovou stránku. Zmíním ještě zajímavý ntptrace, po jehož zadání budou vyhledány a vypsány všechny NTP servery, dle kterých se náš počítač synchronizuje, a to až k úrovni 1.
Časové zóny
Lidé si zvykli rozdělovat den na dvě poloviny, přičemž půlí dne (tzv. poledne) byl okamžik, kdy jim stálo Slunce nad hlavou. To znamená, že na různých místech planety to bylo v jinou dobu. Stejný okamžik poledne mají pouze místa ležící poblíž spojnice severního a jižního pólu. Proto se jim začalo říkat poledníky. Z pohledu pólu se poledníky rozebíhají paprskovitě do kruhu, a tak jsou značeny ve stupních.
Od roku 1884 bylo zavedeno 24 časových pásem (vždy po 15 stupních). Pro zjednodušení nekopírují zóny přímo poledníky, ale většinou hranice států. Některé státy však zahrnují více časových zón. Situaci ještě komplikuje nejednotné používání letního času (Daylight Saving Time - DST). Další důležitou zkratkou je UTC neboli univerzální čas. Ten je odvozen od GMT (Greenwich Mean Time), tedy lokálního času na hvězdárně v Greenwichi (nedaleko Londýna), kudy prochází nultý poledník.
Letní čas bývá tématem mnoha diskusí. Princip je jednoduchý. V době zimního slunovratu je den nejkratší - Slunce vychází kolem 8:00 a zapadá asi v 16:00. Naopak na letní slunovrat je východ už kolem 4:00 a západ až zhruba ve 20:00 (ne-letního času). Většina lidí ale pracuje někde v rozmezí 6:00 až 18:00 a večer bývají vzhůru. K čemu jim je tedy denní světlo ve 4:00, když už v 21:00 je tma? Co takhle kdyby si někdy na jaře (kdy už Slunce vychází kolem 5:00) všichni posunuli své chronometry o hodinu dopředu? Potom když budou astronomicky 4:00, hodinky nám budou nalhávat, že už je 5:00. A budeme mít přírodní světlo až do 22:00 (což je astronomicky 21:00), a tak se bude méně svítit, čímž se ušetří energie, lidský zrak a prý i jiné věci. No a na podzim se to zase vrátí k normálu.
Samotná myšlenka letního času prý pochází již z konce 18. století. Prosadil ji ovšem až William Wilett, který za letní čas lobboval v britském parlamentu od roku 1907. Navrhoval tehdy, aby se během dubna každou neděli posunuly hodiny o 20 minut dopředu a v září obdobně zpět. Ke skutečnému zavedení však došlo až v roce 1916 pro zvýšení efektivity ve válce. Po ní se od této praktiky upustilo a zavedena byla až ve druhé světové, po níž ji většina států zase opustila. Zatím poslední reinkarnace se letní čas dočkal na přelomu 70. a 80. let 20. století, od kdy jej většina států používá dodnes.
V unixovém prostředí se k určení časové zóny používá dvoustupňový systém - oblast a město. Např. k identifikaci časové zóny kdekoli v České republice slouží kombinace Europe/Prague. Oblasti jsou zpravidla podadresáře adresáře /usr/share/zoneinfo (např. /usr/share/zoneinfo/Europe). Města jsou pak binární soubory obsažené v příslušném podadresáři (např. /usr/share/zoneinfo/Europe/Prague).
Různé unixové systémy řeší nastavení časové zóny různě. Některé si ji prostě jen uloží do interních proměnných, jiné používají transparentnější způsob. Ke druhé skupině patří i Linux. Ten po zadání zic -l vytvoří symbolický odkaz s umístěním /etc/localhost. Odkaz míří na příslušný soubor v adresářové struktuře /usr/share/zoneinfo. Při nastavení Europe/Prague tak bude provedena operace ln -sf /usr/share/zoneinfo/Europe/Prague /etc/localtime. Výsledek můžeme zkontrolovat pomocí ls -l /etc/localtime a samozřejmě příkazem date.
Tyto soubory popisují všechny důležité parametry příslušné oblasti - především časový posun proti UTC a pravidla fungování DST. Dohromady pak tvoří komplexní databázi zahrnující celý svět. Tuto databázi je nutné čas od času aktualizovat (dochází ke změnám názvů států, pravidel uplatňování DST apod.) Tvorbu nových souborů časových zón přibližuje následující text.
Tvorba souborů časových zón
Jak již bylo zmíněno, informační soubory časových zón mají binární (tj. nikoli textový) formát. Aby ovšem byla jejich tvorba nepočítačově myslícím bytostem usnadněna, existuje program zic (Zone Info Compiler), který dokáže z textového souboru s odpovídajícím obsahem vytvořit příslušné (jeden nebo více) binární soubory.
Zdrojový text časové zóny (jak můžeme takový textový soubor označit) obsahuje tři typy datových řádků a komentáře. Komentáře začínají znakem #, podobně jako u jiných zdrojových kódů. Datové řádky sestávají z předepsaného počtu polí oddělených bílými znaky (mezera, tabulátor).
Prvním typem řádků je Rule (pravidlo). Obsahuje jméno, rok od kdy a do kdy je uplatňováno, typ, měsíc, den a čas uplatnění pravidla a změna ve jménu zóny. Příkladem nechť jsou dva řádky popisující situaci České republiky:
# NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule M-Eur 1981 max - Mar lastSun 2:00s 1:00 " DST" Rule M-Eur 1996 max - Oct lastSun 2:00s 0 -
Je zde uvedeno, že od roku 1981 se každou poslední neděli v březnu ve 2 hodiny ráno posouvá čas o jednu hodinu dopředu a ke jménu časové zóny se přidává DST. Od roku 1996 se potom čas vrací zpět každou poslední říjnovou neděli. Dále se v souboru uplatňují řádky typu Zone (pásmo):
# NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Prague 1:00 M-Eur MET%s
Za řetězcem Zone vidíme jméno zóny, rozdíl od GMT (resp. UTC), odkaz na pravidla (souvisí s položkou NAME v řádcích Rule) a formát jména zóny. Jméno zóny může obsahovat značku %s, která představuje proměnlivou část definovanou polem LETTER/S v řádcích Rule. Položka UNTIL (do kdy) je nepovinná.
Posledním typem datového řádku je Link. S jeho pomocí můžeme jedné časové zóně přiřadit dvě jména. Pokud bychom jí chtěli dát jmen více, musíme tento řádek použít několikrát. Kupříkladu pro vytvoření zón CET a MET se stejnými pravidly jako Europe/Prague, bychom do souboru přidali:
Link Europe/Prague CET Link Europe/Prague MET
Dejme tomu, že jsme uložili výše uvedené datové řádky (a komentáře) do souboru CET.txt. Dále si vytvoříme pracovní adresář TZ ve stejném adresáři, kam jsme soubor uložili. Nyní stačí v tomto adresáři provést příkaz /usr/sbin/zic -d TZ CET.txt a do adresáře TZ se vygenerují soubory CET a MET a vznikne v něm podadresář Europe, kde se objeví soubor Prague.
Takto vytvořené soubory lze nakopírovat (s právy superuživatele) do příslušných systémových adresářů a použít jako pravidla chování naší časové zóny. Doporučuji však používat originální systémové soubory. Pro bližší informace o programu zic a formátu zdrojových souborů odkazuji na manuálovou stránku zic.
Pokud ale nejsme zarytými antipragocentristy (kteří si chtějí vyrobit vlastní zónu - třeba Europe/Olomouc), bude nám stačit občas aktualizovat systém, resp. balíček, kterému soubory z adresáře /usr/share/zoneinfo patří. Co nás ale bude zajímat určitě, je, jak sdělit systému, ve které zóně se nacházíme. Je to velmi jednoduché.
A co v případě, kdy chcete jen zjistit aktuální čas v Sydney a nechcete kvůli tomu měnit systémové nastavení nebo na daném počítači nemáte rootovská práva? Rada je jednoduchá - program zdump. Syntaxe je také jednoduchá - zdump časová/zóna. Např. pro zmiňovaný případ by stačilo zadat /usr/sbin/zdump Australia/Sydney.
Pro Českou republiku stačí zadat příkaz zic -l Europe/Prague -p Europe/Prague. Přepínač -l se postará o nastavení systémové lokální zóny, -p potom o nastavení pravidel dané zóny při použití posixového formátu systémových proměnných. Není asi třeba zdůrazňovat, že k této operaci potřebujeme práva superuživatele. Chování systému si můžeme vyzkoušet následujícím sledem příkazů:
$ zic -l US/Alaska -p US/Alaska $ date So čec 30 13:53:53 AKDT 2005 $ zic -l Europe/Prague -p Europe/Prague $ date So čec 30 23:54:11 CEST 2005
To ale není k časovým zónám vše. Aby totiž mohl systém aktuální čas pro nastavenou zónu vypočítat, musí vědět, z čeho vycházet. Přece z hardwarových hodin - samozřejmě. Ale ty uchovávají hodnotu pouze o datu a čase. Ne o časové zóně. Proto musí systém vědět, v jakém čase tikají interní hodiny. Jsou v podstatě dvě možnosti. Buď máte hodiny nastaveny na UTC (dříve GMT), nebo na místní čas.
Druhou možnost volí většinou lidé, kteří na svém PC provozují vedle unixových systémů také takové, které se řídí přímo hardwarovými hodinami. Je to poněkud nešťastný přístup a to nejen vzhledem k nepřesnosti těchto hodin. Problém nastává také tehdy, kdy se tyto systémy snaží pseudointeligentně posunout hardwarové hodiny na letní čas či zpět. Unixové systémy jsou v tomto směru ohleduplnější. Nechávají hardware být a pouze zobrazují to, co dopočítají dle údajů o příslušné zóně. Máte tak přirozeně zaručeno i automatické "přepínání" letního času.
Zda hardwarové hodiny běží na UTC, nebo místním čase, nastavíme v textovém konfiguračním souboru, který bude čten vždy při startu systému. Různé distribuce používají různé soubory s různou syntaxí. Ukažme si, jak sdělit některým systémům, že interní hodiny tikají v rytmu UTC:
- Red Hat, Mandriva, Aurox apod. - soubor /etc/sysconfig/clock musí obsahovat řádek UTC=true (v systému SpareMiNT jsem se setkal též se syntaxí CLOCKMODE=GMT);
- Debian - v souboru /etc/default/rcS musí být přítomen řádek UTC=yes;
- Slackware - konfigurační soubor /etc/hardwareclock musí obsahovat řádek UTC.
Pokud vám ruční úprava těchto textových souborů nevyhovuje, přináší většina distribucí textový konfigurační nástroj timeconfig. Ten umožňuje (s výjimkou verze pro Slackware) také nastavení časové zóny. Vedle tohoto nástroje nám samozřejmě moderní distribuce přinášejí různé grafické nástroje, kde si můžeme třeba časovou zónu vybrat kliknutím na příslušné místo na mapě světa. V odvozencích Red Hatu najdeme program system-config-time, v Mandrivě je to Ovládací centrum-Systém-Úprava data a času.
Provádění akcí v zadaném čase - at
Poté, co jsme úspěšně nastavili přesný čas a časovou zónu ve svém systému, můžeme začít využívat některé systémové služby, které jsou na čase založeny. Jednou z nich je program at (anglická časová předložka "v"), který slouží k provádění určitých operací v zadaný čas. Jde o aplikaci pracující na bázi klient-server. Server se jmenuje atd a na většině systémů se spouští automaticky během jejich startu.
Samotný program at je tedy klientem, který nám umožní určit čas a zadat posloupnost příkazů, které mají být provedeny. Vyzkoušejme si jednoduchý příklad. Na příkazový řádek zapíšeme at s příslušným časem, např. za 2 minuty od daného okamžiku, např. at 10:33 a potvrďme klávesou [Enter]. Odezvou je nám prompt ve tvaru at>. To je v pořádku, protože nyní máme vkládat příkazy, které budou provedeny.
Při úkolování at je dobré si uvědomit, že příkazy mohou být vykonávány i v době, kdy příslušný uživatel není přihlášen. Budou však vykonávány pod jeho právy. Z toho mj. vyplývá, že pomocí at nelze spouštět grafické aplikace. Ani textové aplikace nemají kam směřovat svůj výstup, ale ve spuštění jim to nezabrání.
Když necháme proběhnout nějaký příkaz nezávislý na standardním vstupu a výstupu, svou práci v zadaný čas bez problému vykoná. Může jít o práci s lokálními soubory, stažení nějakých dat ze sítě (např. wget), odeslání zprávy na síť, výpočtově náročnou operaci (kompilace) nebo třeba vypnutí počítače (pokud k tomu máme oprávnění).
Nevýhodou je, že když se operace nepovede, nemáme informace o důvodu tohoto neúspěchu (např. nedostatečná práva, neexistující soubor či nedostupnost sítě). I na to však existuje řešení. Program at totiž umí komunikovat s lokálním poštovním serverem (sendmail apod.) a svůj standardní a chybový výstup tak doručit do vaší lokální poštovní schránky (většinou soubor s vaším uživatelským jménem v adresáři /var/spool/mail/).
V rámci jednoho zadání pro at můžeme uvést seznam více příkazů, které budou postupně vykonány. Každý příkaz ukončíme klávesou [Enter]. Pokud už další příkaz vkládat nechceme, ukončíme program at kombinací kláves [Control-d]. Poté se zobrazí číslo naší objednávky (job) a datum a čas, kdy bude opravdu provedena.
Pokud se vám nástroj at zalíbí, můžete mu zadat úkolů hned celou řadu, a to v různých časech. Jen je dobré mít na paměti, že atd kontroluje seznam úkolů jen jednou za minutu, takže úkoly nelze plánovat na sekundy. To lze obejít tak, že jako první ze zadaných příkazů dáte sleep n, kde n je počet sekund.
Podobně jako v případě tiskové fronty (cups, LPRng) máme nástroje k řízení fronty objednávek zadaných přes at. Pomocí atq si můžeme nechat tento seznam zobrazit. Vidíme v něm pořadové číslo objednávky (job), datum a čas pro její provedení a jméno uživatele, který ji zadal.
Pokud se nám nějaká z našich objednávek znelíbí, můžeme ji před jejím provedením z fronty odstranit. Slouží k tomu příkaz atrm. Jeho jediným parametrem je číslo objednávky, např. atrm 5. Root může samozřejmě mazat i objednávky jiných uživatelů.
Pro řízení přístupu ke službě at obecně lze využít seznam zakázaných (/etc/at.deny) nebo povolených (/etc/at.allow) uživatelů. Pokud existuje soubor /etc/at.allow, musíte v něm být uvedeni, abyste mohli at používat. Jinak stačí, když nejste uvedeni v souboru /etc/at.deny.
Opakované provádění akcí - cron
Pomocí cronu lze naplánovat opakované provádění nějaké operace po minutách, hodinách, dnech, týdnech, měsících nebo i jen jednou za rok. Ačkoli je jeho určení podobné programu at, filosofie fungování a obsluhy je zcela odlišná. Snad až na to, že i cron má svého démona na pozadí - crond - a také že výstup prováděných příkazů směřuje do lokální pošty.
Mnoho uživatelů ptá, co se stane, když je počítač vypnutý v době, kdy má cron provádět nějaké úkoly. Naštěstí ne každý počítač s Linuxem je dnes server, a tak je tato otázka na místě. Existuje program anacron, který se spouští při každém startu systému. Srovnáním záznamů o posledním vypnutí počítače a tabulek crontab zjistí, které úkoly neproběhly, jak měly, a naplánuje jejich provedení na nejbližší možnou dobu, tj. zpravidla po startu systému, aby jej to nezdržovalo.
Seznamy úkolů si cron uchovává ve zvláštních tabulkách zvaných crontab. Každý uživatel má přitom svou vlastní. Jsou uchovávány ve formě textových souborů v adresáři /var/spool/cron/ a jejich názvy odpovídají jménům uživatelů (podobně jako poštovní schránky ve /var/spool/mail/).
Vedle uživatelských tabulek existuje ještě jedna systémová. Nachází se v souboru /etc/crontab. Cron pak každou minutu prochází všechny tabulky a provádí úkoly v nich zadané a připadající na daný čas.
Pro tvorbu, prohlížení, úpravy a mazání tabulek slouží program crontab. Nejsnazší je prohlížení tabulky pomocí crontab -l. Je to stejné, jako kdyby uživatel Petr zadal příkaz cat /var/spool/cron/petr.
Podobně smazání tabulky (rm /var/spool/cron/petr) lze nahradit destruktivním crontab -r. Zde však crontab upozorní patřičným způsobem crond na nastalou změnu. Z téhož důvodu bychom soubory tabulek neměli ručně editovat.
K vytváření a úpravám tabulek slouží crontab -e. Zklamán však bude každý, kdo by čekal důmyslné uživatelské rozhraní pro zadávání úkolů a periody jejich opakování. Tento příkaz pouze spustí textový editor a otevře v něm naši tabulku z /var/spool/cron/.
Standardně se spouští přednastavený systémový editor, např. vi. Pokud se vám to stalo a nevíte, jak ven, stačí stisknout kombinaci kláves, která vyvolá znak dvojtečku (:), potom zadat q a stisknout [Enter]. Chcete-li, aby crontab využíval jiný editor (já třeba preferuji kwrite), nastavte nejprve proměnnou EDITOR. Lze toho docílit např. zápisem EDITOR=kwrite crontab -e.
Nyní vidíme původní obsah naší tabulky nebo prázdný soubor (to pokud naše tabulka dosud neexistovala). Pokud chcete vidět nějakou tabulku pro inspiraci, zkuste si zobrazit tu systémovou (např. příkazem cat /etc/crontab).
Zajímavým problémem, který musejí správci čas od času řešit, je spuštění nějaké úlohy pomocí cronu poslední den v měsíci. Na rozdíl od minut, hodin, dnů v týdnu a měsíců nemá tato veličina jednoznačnou maximální hodnotu. V praxi se to většinou řeší tak, že se spustí skript každého 28., 29., 30. i 31. dne v měsíci, přičemž tento skript rozhodne, zda jde o poslední den v měsíci (typicky zda měsíc dnes je roven měsíci zítra), a pouze v tomto případě provede další operace.
Tabulka crontab může obsahovat tři typy řádků. Ty, které začínají znakem #, jsou komentáře. Druhým typem je nastavení proměnných, např. SHELL=/bin/bash nastaví shell pro provádění zadaných příkazů na Bash, MAILTO=petr zase určí, že maily s výstupy příkazů se budou posílat uživateli Petr místo autoru tabulky. Posledním, a nejdůležitějším, typech řádků crontab jsou ty, kde jsou definovány časy a k nim příslušející akce. Sestávají z šesti polí oddělených mezerou (nebo tabulátorem):
- 1. pole znamená minuty, může nabývat hodnot od 0 do 59;
- 2. pole představuje hodiny v hodnotách 0-23;
- 3. pole jsou dny v měsíci, tj. 1 až 31;
- ve 4. poli jsou měsíce, tedy čísla od 1 do 12 nebo zkrácené anglické názvy;
- 5. pole obsahuje dny v týdnu, které mohou být opět zadány anglickou zkratkou nebo číslem 0-7, kde 0 i 7 je neděle.
- 6. pole (přesněji řečeno celý zbytek řádku) je určeno pro samotný příkaz, který může mít libovolné množství voleb a parametrů.
A jak že to vlastně funguje? Je to prosté. Pomocí prvních pěti polí můžeme stanovit frekvenci opakování. Nemusíme přitom využít všechna pole. Ta, na kterých nám nezáleží, vyplníme hvězdičkou.
Např. úloha vykonávaný každý den v měsíci bez ohledu na den v týdnu vždy v 8:45 bude uvozena záznamem 45 8 * * *. Pro její vykonávání pouze v desátý den měsíce by sloužil zápis 45 8 10 * *, kdyby to měla být každá středa, tak zase 45 8 * * 3.
Více čísel v jednotlivých polích můžeme psát formou čárkami odděleného seznamu (např. 45 8 10,20,30 * * pro desátého, dvacátého a třicátého). Přípustné jsou také rozsahy (45 8 10-20 * *, tedy desátého až dvacátého) a kombinace obojího (45 8 10-15,20-25 * *, tj. desátého až patnáctého a dvacátého až pětadvacátého v 8:45 každý měsíc).
Velmi zajímavá je možnost využití znaku lomítko v číselných hodnotách. Kupříkladu zápis 0-23/2 (v druhém poli) znamená každou sudou hodinu nebo 11-23/3 odpovídá hodnotám 11, 14, 17, 20, 23. Pokud bychom chtěli naši aktivitu provádět jednou za tři dny, můžeme zadat 45 8 1-31/3 * *.
Jak již bylo uvedeno, do 6. pole vkládáme příkaz, který má být proveden. Může obsahovat i všechny potřebné parametry a přepínače oddělené mezerami. V systémové tabulce (/etc/crontab) je na šestém místě jméno uživatele, pod jehož právy se má úloha provést. Příkaz s parametry je potom sedmý.
Jistým omezením je fakt, že z crontab nelze přímo spouštět více příkazů současně. Lze to však vyřešit tím, že necháme spustit shellový skript, který vykoná vše potřebné (tvorba skriptů viz seriál Bash, 8. díl).
Výpis obsahu ukázkového souboru /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly
Další časové programy
Vedle již zmíněných více či méně systémových nástrojů pro práci s časem existuje i řada menších prográmků, jejichž činnost má s časem co do činění. Jedním z nich je time, od nějž uživatelé často mylně očekávají vypsání aktuálního času. V jeho popisu práce je však zatížení zdrojů, lidsky řečeno, jak dlouho byl prováděn zadaný příkaz.
Použití time je snadné. Prostě jej napíšeme na příkazový řádek před jakýkoli jiný zadávaný příkaz. Smysl to má samozřejmě především tehdy, kdy příkaz bude vykonávat delší dobu, nejen pár tisícin sekundy, jako je tomu běžně u cd, ls apod. Zkuste např. time find /usr -iname "*linux*", čímž získáte seznam souborů v adresářové struktuře /usr, jejichž jméno obsahuje skupinu znaků linux.
Na konci výpisu uvidíme údaj o spotřebovaném čase. V různých verzích a systémech se formát tohoto výpisu liší. Objevuje se tam ale určitě celkový čas běhu procesu (real, elapsed), čas zabraný v uživatelském (user) a systémovém (sys, system) režimu a zatížení CPU (v procentech).
Time zná také několik přepínačů. Zajímavý je time -p prikaz, který vypíše údaje o spotřebovaném čase ve třech řádcích dle normy Posix. Ještě zajímavější může být time -v prikaz, jehož výsledkem bude podrobný rozbor s asi 20 různými výstupními hodnotami. Další přepínače a možnost formátování výstupu dle vlastního přání najdete v manuálové stránce (man time).
Čas a datum již zobrazovat umíme. Což takhle dát si kalendář? Není problém, od toho máme v GNU program cal. Zadaný bez parametrů vypíše strukturu aktuálního měsíce s vyznačením dnešního dne. Pomocí cal -3 obdržíme navíc předchozí a následující měsíc. Celý rok zobrazíme zadáním cal -y. Pro ty, kdož preferují kontinentální začátek týdne, tedy pondělí, před anglosaskou nedělí, je zde cal -m.
Několik poznámek ke kalendářům. Vedle solárního existují také lunární (např. arabský). Křesťanský kalendář začíná rokem 1, před kterým je rok 1 před Kristem (tj. -1, nikoli 0). Původní algoritmus byl dvakrát upraven, aby lépe odrážel fakt, že rok nemá přesně 365 dnů. První úpravu (juliánský kalendář) provedl Gaius Iulius Caesar. Druhou roku 1582 papež Řehoř XIII. (gregoriánský kalendář). Tehdy se již kalendář rozcházel se skutečností o 10 dnů, a proto byly dny 5. října 1582 až 14. října 1582 včetně vynechány. Po čtvrtku 4. října přišel pátek 15. října.
Parametry lze přirozeně kombinovat, takže tři měsíce po evropsku dostaneme zápisem cal -3m. Zajímavostí je tzv. juliánské datum, reprezentované pořadovým číslem dne v roce. Zkuste cal -j, resp. cal -jy. Nemusíme se omezovat jen na aktuální měsíc a rok. Pokud chci rychle zjistit, na který den připadnou kulatiny mého známého v březnu 2008, zadám cal 3 2008.
Čas v grafice
Klasikou a jednou z nejstarších aplikací v grafickém prostředí X je program xclock. Dnes je stabilní součástí základního balíku s X serverem (X.org, XFree86). Spustit jej lze z příkazové řádky prostým zadáním xclock. Uvidíme velmi jednoduché analogové hodiny v okně.
V říjnu 1582 zavedli gregoriánský kalendář jen v Itálii, Portugalsku, Španělsku (vč. jihu USA) a části Polska. Další země jej přejímaly postupně. Např. Rakousko a české země poskočily ze 6. na 17. ledna v roce 1584. Britské impérium (vč. severu USA) provedlo změnu v únoru 1752 (viz výsledek příkazu cal 2 1752). Rusko čekalo do února 1918, a kvůli tomu VŘSR připadá dle gregoriánského kalendáře na listopad a pravoslavné Vánoce na leden. Až do roku 1927 se změnou otálelo Turecko.
Chování xclock můžeme ovlivnit přepínači. Např. xclock -update 1 přidá vteřinovou ručičku. Dáváte-li přednost digitálnímu zobrazení, zkuste xclock -digital -update 1. Zajímavostí je xclock -digital -utime -update 1, který zobrazuje počet sekund uplynuvších od začátku unixové epochy, tj. od 1.1.1970 (viz systémový čas).
Esteticky propracovanější hodiny pro váš desktop lze nalézt v podobě programu xonclock. Umožní vám hrát si s parametry (velikostí, barvou apod.) jednotlivých ručiček, vybírat přednastavené vzhledy (skiny) apod. Doporučuji spouštět s parametry xonclock -s -d --top. Další informace o xonclock najdete v LinuxEXPRESu 10/2005.
A na závěr něco zcela klikacího, zvláště pro příznivce KDE. Soustředíme se na dolní lištu zvanou Kicker. V její pravé části se většinou nacházejí hodiny. Pokud je tam nemáte, lze je přidat kliknutím pravým tlačítkem myši na volné místo na panelu a výběrem Přidat do panelu-Applet-Hodiny. Po kliknutí pravým tlačítkem na zobrazované hodiny můžete měnit jejich typ (analogové, digitální nebo slovní), zobrazované časové pásmo apod. Po kliknutím levým tlačítkem se zobrazí velmi praktický kalendář.
Kicker však nabízí i další zajímavé applety související s časem. Jmenujme alespoň fáze měsíce, ukazující graficky podíl osvětleného povrchu měsíce viditelného ze Země. Dále pak světové hodiny ukazující mapku světa s rozlišením hranic dne a noci a mnoha body. Když nad bod najedete kurzorem myši, zobrazí se jeho jméno a přesný čas v dané lokalitě.
Povídání uzavřu poněkud technoidním appletem "binární hodiny". Ten zobrazí šest sloupců po čtyřech žárovičkách. Ty se zdánlivě chaoticky rozsvěcují a zhasínají. Jde však o zobrazování aktuálního času v binární podobě. Sloupce znamenají totéž, co číslice na digitálkách v desítkovém vyjádření, tj. (zleva) desítky hodiny, hodiny, desítky minut, minuty, desítky sekund, sekundy. Světýlka ve sloupcích (zespodu) jedničku, dvojku, čtyřku a osmičku. Příjemnou zábavu.
Myslím, že na základě výše uvedeného lze vyslovit závěr, že práce s časem je v Linuxu podporována. Text sice nebyl krátký, ale na druhou stranu ani vyčerpávající. Nezmiňuji např. obsluhu hardwarových zařízení pro příjem radiového synchronizačního signálu. Zatím však scházejí ovladače pro přenos hardwaru a uživatelů v čase (a to oběma směry!).