Fcron – trochu iný plánovač
Pravdepodobne poznáte štandardný plánovač cron (presne Vixie Cron), ktorý je súčasťou väčšiny dnešných distribúcií Linuxu. Má však jednu veľkú nevýhodu na strojoch, ktoré nebežia vkuse (osobné počítače, notebooky), nikdy nie sú spúšťané úlohy, ktoré mali byť vykonané v dobe vypnutia…
Obsah článku
Tento nedostatok aspoň čiastočne rieši nástroj anacron, ktorý sa postará aspoň o spúšťanie pravidelných úloh (denné, týždenné a mesačné), ale i tak je cron len ťažko využiteľný napríklad ako pripomienkovač narodenín… Chvíľu som sa pohrával aj s myšlienkou nejakého grafického plánovača, ale kvôli zopár narodeninám mi to príde zbytočné, a tak som začal pátrať a našiel som fcron.
Fcron je náhradou štandardného Vixie cron, avšak bol navrhnutý s ohľadom na systémy, ktoré nebežia 24 hod denne a 7 dní v týždni. Môžete ho použiť ako plnohodnotnú náhradu cron, alebo ako jeho doplnok. Obdobne ako cron, umožňuje používateľom definovať si ich vlastné zoznamy úloh, a to nie len skutočným používateľom, ale prakticky každému používateľovi (aj systémovým). Rovnako ako pri fcron, je najmenšou jednotkou spustenia minúta.
Tip
Zlou správou je, že fcron bol z Debianu odstránený, môžete si ho skompilovať zo zdrojových kódov alebo použiť balík z môjho úložiska…
Zoznamy úloh
Na prácu s úlohami slúži nástroj fcrontab, ktorého použite je veľmi podobné nástroju crontab z Vixie Cron. Pomocou nástroja fcrontab možno:
vypísať obsah svojho zoznamu úloh:
fcrontab -l
odstrániť svoj zoznam úloh:
fcrontab -r
upraviť svoj zoznam úloh:
fcrontab -e
obnoviť svoj zoznam úloh, teda znova vygenerovať binárnu podobu zoznamu úloh, čo bude mať za následok zahodenie informácií o poslednom vykonaní úlohy:
fcrontab -z
Každý vyššie spomenutý príkaz možno spustiť v voľbou -n, hoci prakticky to má zmysel len pri úprave, ktorá zaistí, že pri úprave zoznamu úloh, budú aj nezmenené úlohy považované za nové. Bez tejto voľby sa fcron snaží zachovať maximum informácií o úlohách, ktoré menené neboli (čas a úloha), najmä však informácie o nasledujúcom spustení.
Všetky spomenuté možnosti je možné robiť aj so zoznamom úloh iného používateľa, avšak na toto sú potrebné práva root. Napríklad na vypísanie zoznamu úloh používateľa slavko treba zadať:
fcrontab -l slavko
Fcron umožňuje vytvoriť zoznam úloh pre každého používateľa, ktorý má
záznam v /etc/passwd
, teda ja pre systémových používateľov. Okrem
skutočných účtov ešte rozpoznáva používateľa systab, ktorý slúži
na správu systémového zoznamu úloh.
Zoznam úloh možno importovať z externého súboru pomocou:
fcrontab súbor používateľ
Príkaz na úpravu zoznamu úloh spúšťa textový editor, v ktorom môžete jednotlivé úlohy upravovať. V Debiane je možné tento editor pre celý systém nastaviť pomocou systému alternatív:
update-alternatives --config editor
Používateľ si ho potom môže zmeniť pomocou premennej prostredia $EDITOR.
Riadenie prístupu
Ako som spomenul, fcron dokáže pracovať so zoznamami úloh hociktorého
existujúceho používateľa, ale niekedy je žiadúce toto správanie
obmedziť, na čo slúžia súbory riadenia prístupu /etc/frcon.allow
a
/etc/fcron.denny
. Ako mená súborov napovedajú, do prvého možno
vkladať mená používateľov, ktorí majú právo vytvárať si zoznamy úloh a
do druhého zase mená používateľov, ktorým je toto právo odopreté.
Okrem mien používateľov môže byť v týchto súboroch použité kľúčové
slovo all, ktoré označuje všetkých používateľov. Nasledujúca tabuľka
ukazuje výsledok rôznych kombinácií zápisu do súborov fcron.allow
a
fcron.denny
:
používateľ | fcron.allow | fcron.denny | výsledok |
---|---|---|---|
slavko | all | - | môže |
slavko | - | all | nemôže |
slavko | all | all | nemôže |
slavko | all | slavko | nemôže |
slavko | slavko | - | môže |
slavko | slavko | all | môže |
slavko | - | slavko | nemôže |
slavko | slavko | slavko | nemôže |
Varovanie
Pridanie používateľa do súboru fcron.denny
nebráni spúšťaniu
jeho úloh, ak už má svoj zoznam úloh vytvorený, preto ho treba odstrániť.
Nastavenie prostredia
Úlohy fcrontab
sú spúšťané vždy v novom prostredí, teda nastavenia prostredia nie sú
dedené. V tomto prostredí fcron vždy nastavuje premenné:
USER
aHOME
(z/etc/passwd
) na základe vlastníka tabuľkyfcrontab
, z ktorej pochádza úloha;TZ
na hodnotu voľbytimezone
, keď je táto voľba nastavená;SHELL
, a to buď zfcrontab
, ak tam nie je definovaná, tak zfcron.conf
, a ak nie je definovaná ani tam, tak z/etc/passwd
;- všetky ostatné premenné z
fcrontab
.
Hodnoty premenných HOME a SHELL môžu byť v tabuľke fcrontab zmenené, ale USER nie. Definícia premenných vo fcrontab je vo forme:
meno = hodnota
- medzery okolo znaku = sú voliteľné a ignorované
- medzery na konci sú ignorované
- na vynútenie medzier možno použiť úvodzovky, a to jednoduché alebo dvojité
Predvolene posiela fcron emaily s hlavičkou Content-Type:
nastavenou na „text/plain
“ s parametrom „charset=
“ nastaveným na
kódovanie podľa kódovania prostredia, z ktorého je fcron spustený teda
predvolené nastavenie lokalizácie alebo podľa nastavení premenných
prostredia LC_\*
. V prípade potreby je možné v fcrontab použiť
premenné CONTENT_TYPE
a/alebo CONTENT_TRANSFER_ENCODING
a nastaviť ich
na požadované hodnoty.
V fcrontab
možno použiť aj špeciálnu premennú MAILTO
, ktorá bude
udávať adresáta emailov, ale táto premenná je len kvôli spätnej kompatibilite a
mala by byť používaná voľba mailto
.
Plánovanie úloh
Ak poznáte spôsob vytvárania času spustenia (opakovania) úlohy vo
Vixie cron, môžete tieto znalosti využiť, pretože fcron podporuje
skoro všetko z tohoto cronu. Píšem skoro všetko, pretože nepodporuje
syntax @… (@daily, @monthly, atď) ani definície úloh v /etc/cron.d
.
Naproti tomu, v fcron možno definovať čas spustenia tromi spôsobmi:
- položky @… – založené na čase, ktorý uplynul od štartu
- položky &… – založené na čase a dátume
- položky %… – periodicky spúšťané
Spustenie založené na čase od štartu
Tento typ položiek začína znakom @ a spúšťa úlohy raz po každom uplynutí zadaného intervalu, ale negarantuje konkrétny čas a dátum vykonania úlohy, pretože systém mohol byť spustený prakticky kedykoľvek. Všeobecný syntax zápisu takto spúšťanej úlohy vyzerá nasledovne:
@voľby frekvencia príkaz
Voľbám sa budem venovať neskôr, ale namiesto voľby možno za znak @ zadať číslo, ktoré bude interpretované ako hodnota voľby first(). Frekvencia je, predvolene, počet minút (od spustenia), ale pre dlhšie intervaly možno použiť násobky:
- m – mesiace (4 týždne)
- w – týždne (7 dní)
- d – dni (24 hod)
- h – hodiny (60min)
- s – sekundy
Príklady:
# spustiť každých 5 minúť
@ 5 echo "Prešlo 5 minút"
# prijať emaily každých 30 min
@ 30 getmails -all
# prvý krát spustiť po 5 min, potom každú hodinu
@5 1h echo "Prešla hodina"
# spustiť každých 12 hod a 2 min
@ 12h02 echo "Prešlo 12 hod a 2 min"
# spustiť každý deň
@ 1d echo "systém beží ďalší deň"
Spustenie založené na dátume a čase
Druhý typ položiek začína voliteľným znakom & a spúšťa úlohy v zadaných časoch, ktoré sú definované pomocou piatich časových polí (rovnako ako vo Vixie cron):
&voľby min hod den-mesiaca mesiac deň-týždňa príkaz
Aj tu sa budem voľbám venovať neskôr, ale namiesto voľby možno za znak @ zadať číslo, ktoré bude interpretované ako hodnota voľby runfreq().
Časové polia môžu byť zadané pomocou:
- číslo
- hviezdička
- zoznam
- rozsah
- meno
Povolený rozsah čísel:
- minúta – 0-59
- hodina – 0-23
- deň mesiaca – 1-31
- mesiac – 1-12 (alebo meno)
- deň týždňa – 0-7, pričom 0 i 7 sú nedeľa (alebo meno)
Ak je hodnotou poľa jedno číslo (alebo meno), pole vyhovuje pre túto konkrétnu hodnotu. Ak je hodnotou hviezdička, pole vyhovuje každej hodnote v rozsahu povolenom pre dané pole. Zoznamy sú hodnoty oddelené čiarkami a pole vyhovuje pre každú hodnotu zoznamu.
Rozsahy sú vo forme štart-koniec, a pole vyhovuje pre každú hodnotu rozsahu (vrátane hraničných). K rozsahu možno pridať časť /číslo, ktoré udáva počet preskakovaných hodnôt. Ďalším rozšírením je pridanie jednej alebo viac ~číslo, čo udáva konkrétne hodnoty, ktoré budú preskočené.
Výsledný čas spustenia je určený logickým a všetkých polí, teda aby bola úloha spustená, musia všetky polia zodpovedať aktuálnemu času. Zaujímavou však je kombinácia definície dňa mesiaca (dátumového) a dňa týždňa, pretože tieto polia môžu byť v určovaní termínu spracované dvomi spôsobmi:
- pomocou logického a, teda ak vyhovujú obe polia (predvolene)
- pomocou logického alebo, teda ak vyhovuje jedno z polí (voľba dayor).
Príklady:
# spustí príkaz každý deň o 12:05, 12:35, 13:05, 13:35, 14:05 a 14:35
05,35 12-14 * * * echo "Spustené"
# spustí príkaz každú hodinu v 20, 21, 22, 23 a 24 minúte
20-24 * * * * * echo "Spustené"
# spustí príkaz každú hodinu v 20, 21, 22 a 24 minúte
20-24~23 * * * * * echo "Spustené"
# spustí príkaz každú druhú hodinu v 20, 21, 22 a 24 minúte
20-24~23 */2 * * * echo "Spustené"
# spustiť úlohu o 03.45 alebo po štarte, ak o 03.45 nebol stroj zapnutý
# ~0 zasití, aby úloha nebola spustená v nedeľu 2x
&bootrun 45 03 * * *~0 "Spustené"
Spúšťanie v intervaloch
Tretí typ položiek začína znakom %, nasledovaným kľúčovým slovom a spúšťa úlohu raz v zadanom intervale. Jeho základná syntax vyzerá takto:
%kľúčové_slovo,voľby dátum_a_čas príkaz
I tu popis volieb preskočím a spomeniem len, že ak nie sú použité žiadne voľby, netreba ani čiarku za kľúčovým slovom. Táto voľba je skutočnou silou plánovača fcron, pretože konkrétny čas vykonania úlohy závisí na tom, či a kedy je počítač spustený. Fcron pozná tri typy kľúčových slov tohoto typu položky, pričom prvé dva z nich majú podobné správanie:
- *ly – hourly, daily, monthly a weekly
- mid*ly – midhourly, middaily, nightly, midmonthly a midweekly
Kľúčové slová *ly udávajú interval, ktorý zodpovedá ich menu a spustí úlohu v určenom intervale, keď je počítač spustený. Kľúčové slová mid*ly sa správajú presne rovnako, len interval začína uprostred daného intervalu, takže napríklad %midweekly spustí úlohu medzi štvrtkom a stredou.
Konkrétny čas spustenia úlohy závisí od špecifikácie času a dátumu. Tento časový údaj sa riadi rovnakými pravidlami ako v predchádzajúcom type položky (položky &…), jeho interpretácia je však mierne odlišná. Každá voľba pracuje s iným povinným rozsahom polí (ale môžu byť zadané aj ostatné polia):
kľúčové slovo | časový údaj |
---|---|
hourly, midhourly | minúty |
daily, middaily, nightly, weekly, midweekly | minúty a hodiny |
monthly, midmonthly | minúty, hodiny a dni |
Ak je časový údaj definovaný ako rozsah, je úloha spustená niekedy v tomto rozsahu. Ak je definovaný ako zoznam rozsahov, je úloha spustená raz pre každý rozsah v zozname.
Tretím typom kľúčových slov sú *s, konkrétne:
- *s – mins, hours, days, mons a dow (pracovné dni)
Tieto kľúčové slová spúšťajú úlohy trochu inak, a to raz v každom zadanom časovom intervale, pričom ako interval ignorujú zadané hodnoty s nižším rozsahom ako kľúčové slovo (hours nepovažuje pole s minútami ako definíciu intervalu, ale bude použité ako definícia času vykonania počas intervalu). Časový údaj týchto kľúčových slov sa skladá zo všetkých piatich časových polí.
Príklady:
# bude spustená raz medzi 2.00 a 10.59 a raz medzi 14.00 a 22.59
%daily * 2-10,14-22 echo "dva krát za deň"
# bude spustená každú hodinu, hneď ako je to možné
# napr 16.51, 17.00, 18.00, ...
%hourly * echo "každú hodinu"
# bude spustená raz týždenne 19:00 a 22:59
%weekly * 19-22 echo "raz za týždeň"
# bude spustené každý deň o 19:30, 20:30, 21:30 a o 22:30
%mins 30 19-22 * * * echo "štyri krát za deň"
# bude spustené o 19:30, 20:30, 21:30 alebo o 22:30
%hours 30 19-22 * * * echo "raz za deň"
# spustí príkaz raz medzi 8.00 a 12.59 a raz medzi 14.00 a 18.59
%hours * 8-12,14-18 * * *
Voľby
Voľby, ktoré menia správania spustenia úlohy, možno zadať na samostatnom riadku (potom platia pre zvyšok zoznamu úloh za voľbou) alebo v riadku úlohy. V prípade ich použitia na samostatnom riadku musí riadok začínať výkričníkom, nasledovaný voľbou. Na jednom riadku (v jednej úlohe) je možné zadať viac volieb, tieto sú potom oddelené čiarkami. V definícii volieb nie sú dovolené medzery.
Fcron poskytuje veľa volieb, nebudem tu popisovať všetky, ale len tie (pre mňa) najzaujímavejšie, kompletný popis je v manuálovej stránke:
- bootrun
- platné len pre položky
&...
ak mali byť vykonané počas vypnutia systému, budú vykonané pri štarte - dayor
- polia deň týždňa a deň mesiaca porovnáva pomocou logického alebo
- forcemail
- vynúti poslanie emailu, aj keď nie je žiadny výstup
- mailto(meno)
- meno používateľa alebo emailová adresa adresára emailu (predvolene vlastník
fcrontab
) - nice(číslo)
- mení prioritu spúšťanej úlohy
- lavg(x,y,z)
vloží úlohu do fronty, kde čaká kým nebude load (1 min, 5 min a 15 min) systému nižší ako zadané hodnoty (AND), front dokáže uchovať až 30 úloh
- podobnú úlohu plnia voľby lavg1, lavg5 a lavg15,
- random
- v položkách %… mení čas spustenia úlohy v intervale z hneď ako je možné na „v náhodnom čase“
- rebootreset
- fcron bude po každom reštarte OS považovať úlohu za novú,
je to obdoba voľby
volatile
, ale založená na reštarte systému, nie na reštarte démona - reset
- obnoví predvolené nastavenie všetkých volieb
- runas(meno)
- spustiť s právami iného používateľa, môže použiť len root
- runatreboot
- úloha bude spustená pri štarte systému (teda pri prvom spustení démona fcron po štarte operačného systému)
- runfreq(počet)
- frekvencia spúšťania (ignorované v položkách
@...
), teda spusť len každý n-tý krát - runonce
- po spustení úlohy je nenaplánuje na ďalšie spustenie, kým nebude reštartovaný systém
(ak nie je nastavené
volatile
) alebo kým nebude reštartovaný démon fcron (ak je nastavenévolatile
) - serial
- nastavuje sériové (postupné) spúšťanie úloh, pričom naraz je
spustená najviac jedna sériová úloha najviac jednu zo sériových úloh,
ktoré majú nastavené rovnaké hodnoty
lavg()
(alebolavg1
,lavg5
čilavg15
) - serialonce
- udáva, či majú (môžu) byť v sériovom fronte ukladané úlohy aj viackrát, teda ak sériová úloha čaká vo fronte a nastane čas jej ďalšieho spustenia, či má byť znova pridaná do frontu
Tam kde nie je uvedený parameter voľby je voľba logickým prepínačom a
pridanie parametra (false
) má za následok opačný význam voľby. Ďalšie
voľby nájdete v manuálovej stránke fcrontab(5).
Uspávanie
Pri zobudení počítača z uspania/hibernácie je potrebné démona fcron
reštartovať, pretože má nesprávne vypočítané časy budúceho spustenia
úloh. V Debiane sa o to postará jednoduchý skript, ktorý možno
umiestniť do /etc/pm/sleep.d/
a nazvať napríklad 50fcron
:
#!/bin/sh
# This script makes fcron jobs start to run when the machine is woken up.
# For a laptop, these are the closest parallels to turning on a desktop.
case $1 in
hibernate|suspend)
[ -x /etc/init.d/fcron ] && /etc/init.d/fcron stop
;;
thaw|resume)
[ -x /etc/init.d/fcron ] && /etc/init.d/fcron start
;;
esac
Nahradenie Vixie cron
Ako spomínal na začiatku, fron môže plnohodnotne nahradiť štandardný cron, čo sa týka používateľských zoznamov úloh to už iste dokážete posúdiť aj sami. V podstate fcron plne podporuje syntax plánovania úloh cron, s tým, že nepodporuje (respektíve dáva iný význam) položkám definovaným pomocou @hourly a podobne.
Trochu väčší, avšak riešiteľný problém, sú adresáre /etc/cron.*
, do
ktorých inštaluje svoje úlohy mnoho ďalších balíkov. Bez väčších
problémov možno naplánovať spúšťanie skriptov v adresároch cron.daily
,
cron.hourly
a cron.mounthly
, pretože sa naozaj jedná o skripty
(poslúži príkaz run-parts z balíka debianutils). Najtvrdším
orieškom ostáva adresár /etc/cron.d
, keďže súbory v tomto adresári nie sú
skripty, ale úlohy cronu s rovnakou syntaxou ako je v crontab. Aj toto
je však riešiteľné, hoci pomocou samostatného skriptu, ktorý je
súčasťou zdrojových kódov frcon a určite sa k tomu ešte vrátim, ale
inokedy.
Nahradenie skratiek Vixie cron
Démon fcron teraz rozumie týmto skratkám, používaným v tabuľkách úloh Vixie cron:
skratka Vixie cron | význam | ekvivalent fcron | odporúčaná alternatíva |
---|---|---|---|
@reboot | Spustiť raz, pri štarte | @runatreboot,runonce(true) | |
@yearly | Spustiť raz za rok | 0 0 1 1 * | @ 12m |
@annually | (rovnaké ako @yearly) | 0 0 1 1 * | @ 12m |
@monthly | Spustiť raz za mesiac | 0 0 1 * * | @ 1m |
@weekly | Spustiť raz za týždeň | 0 0 * * 0 | @ 1w |
@daily | Spustiť raz za deň | 0 0 * * * | @ 1d |
@midnight | (rovnaké ako @daily) | 0 0 * * * | |
@hourly | Spustiť raz za hodinu | 0 * * * * | @ 1h |