Jestliže potřebujete v Linuxu naplánovat jednorázovou úlohu, cron je zbytečně složitý. V takovém případě se nabízí využít nástroje z rodiny příkazů at
. Pokud byste pak chtěli procesy spouštět pouze tehdy, když váš systém nemá velké zatížení, můžete sáhnout po batch
.
Plánování úloh v Linuxu s využitím at
Démon cron spravuje seznam úkolů, které automaticky spouští v definovaných časech. Tyto úlohy a programy běží na pozadí v naplánovaných intervalech, což nabízí velkou flexibilitu pro plánování opakujících se akcí. Cron je ideální pro úlohy, které je potřeba spouštět pravidelně – ať už jde o každou hodinu, denně v určitou dobu, nebo třeba jednou za měsíc či rok.
Nicméně, v situaci, kdy potřebujete spustit úlohu pouze jednou, cron není ideální. Sice by se to s cronem dalo zařídit, ale museli byste následně odstranit záznam z crontabu po dokončení úlohy, což je nepraktické.
S velkou pravděpodobností se s problémem, na který narazíte v Linuxu, již setkal někdo jiný. A díky tomu, že systémy podobné Unixu jsou s námi tak dlouho, je velká šance, že existuje řešení i pro vaši situaci.
Pro výše zmíněný problém, kdy potřebujete jednorázově naplánovat úlohu, se nabízí právě příkaz at
.
Instalace příkazu at
Příkaz at
jsme museli instalovat na Ubuntu 18.04 a Manjaro 18.1.0, zatímco na Fedoře 31 byl již předinstalován.
Pro instalaci na Ubuntu použijte následující příkaz:
sudo apt-get install at
Po dokončení instalace spusťte démona at
pomocí tohoto příkazu:
sudo systemctl enable --now atd.service
Na Manjaru provedete instalaci následujícím příkazem:
sudo pacman -Sy at
Po úspěšné instalaci aktivujte démona at
použitím následujícího příkazu:
sudo systemctl enable --now atd.service
V jakékoliv distribuci můžete ověřit, že démon atd
běží pomocí tohoto příkazu:
ps -e | grep atd
Interaktivní použití příkazu at
Pro použití příkazu at
musíte zadat datum a čas, kdy má být úloha spuštěna. Způsoby, jakými můžete zadávat čas, jsou velmi flexibilní, což si ukážeme dále v tomto textu.
I když používáte příkaz at
interaktivně, musíte předem specifikovat datum a čas. Pokud do příkazového řádku nezadáte žádný čas nebo zadáte něco, co se nedá interpretovat jako čas, dostanete odpověď „špatný čas“, jak je vidět níže:
at
at banana
Data a časy mohou být zadávány explicitně nebo relativně. Například, pokud chcete, aby se příkaz spustil za minutu, at
chápe pojem „teď“, takže můžete použít klíčové slovo now
a přidat k němu jednu minutu, takto:
at now + 1 minute
at
vypíše zprávu a výzvu at>
, kde očekává, že zadáte příkazy, které chcete naplánovat. Nejprve si ale všimněte zprávy, která se zobrazí, jak je uvedeno níže:
Zpráva uvádí, že instance shellu sh
bude spuštěna a provede se v ní sada příkazů. Vaše příkazy se tedy nespustí v prostředí Bash, ale v shellu sh
, který je sice s Bashem kompatibilní, ale má chudší sadu funkcí.
Pokud vaše příkazy nebo skripty budou využívat funkce specifické pro Bash, které nejsou dostupné v shellu sh
, akce selže.
Pro ověření, zda vaše příkazy a skripty fungují správně v shellu sh
, použijte příkaz sh
, který spustí shell sh
:
sh
Příkazový řádek se změní na znak dolaru ($) a nyní můžete ověřit, zda vaše příkazy fungují správně.
Pro návrat do prostředí Bash použijte příkaz exit
:
exit
Nebudete vidět žádný standardní výstup nebo chybové zprávy od příkazů. Důvodem je, že shell sh
běží jako úloha na pozadí a nemá žádné rozhraní s obrazovkou.
Jakýkoli výstup z příkazů – ať už úspěšný, nebo chybový – vám bude zaslán e-mailem. E-mail se odesílá prostřednictvím interního poštovního systému tomu uživateli, který příkaz at
zadal. Je tedy potřeba mít nastavený a nakonfigurovaný tento interní e-mailový systém.
V mnoha (většině) linuxových systémech není interní e-mailový systém aktivní, protože se používá jen zřídka. Pokud již nějaký interní poštovní systém používají, jedná se obvykle o systémy jako sendmail nebo postfix. Pokud váš systém interní e-mailový systém nemá, můžete nechat skripty zapisovat do souborů nebo přesměrovávat jejich výstup do souborů pro logování.
Pokud příkaz nevygeneruje žádný standardní výstup nebo chybové zprávy, e-mail neobdržíte. Mnoho linuxových příkazů signalizuje úspěch tím, že nehlásí žádnou chybu, takže ve většině případů se vám žádný e-mail neobjeví.
Nyní je čas zadat příkaz. V tomto příkladu použijeme malý skript s názvem sweep.sh
, který odstraňuje soubory s příponami *.bak, *.tmp a *.o. Zadejte cestu k příkazu, jak je znázorněno níže, a stiskněte klávesu Enter.
Zobrazí se další příkazový řádek, a můžete zadat libovolný počet příkazů. Nicméně, pro lepší přehlednost je většinou výhodnější mít všechny příkazy v jednom skriptu, a ten z příkazu at
pouze zavolat.
Stisknutím Ctrl+D dáte vědět, že jste dokončili zadávání příkazů. Zobrazí se <EOT>
, což je zkratka pro konec přenosu. Poté se vám zobrazí číslo úlohy a čas, kdy má být spuštěna, jak je uvedeno níže:
Po provedení úlohy zadejte pro kontrolu interní pošty:
Pokud žádná pošta není, předpokládejte, že se úloha provedla v pořádku. V tomto případě můžete samozřejmě zkontrolovat, zda se soubory *.bak, *.tmp a *.o smazaly, abyste se ujistili, že příkaz fungoval.
Chcete-li provést celou akci ještě jednou, zadejte:
at now + 1 minute
Po jedné minutě zadejte následující příkaz a zkontrolujte poštu znovu:
Výborně, máme novou poštu! Pro přečtení zprávy číslo jedna stiskněte 1 a poté Enter.
Obdrželi jsme e-mail od na
, protože příkazy ve skriptu vygenerovaly chybové zprávy. V tomto příkladu nebyly žádné soubory ke smazání, protože skript jsme už jednou spustili, a ty soubory smazal.
Stiskněte D+Enter pro smazání e-mailu a Q+Enter pro ukončení poštovního programu.
Formáty zadávání data a času
Máte velkou flexibilitu v tom, jaké formáty času můžete použít. Zde je několik příkladů:
Spuštění v 11:00:
at 11:00 AM
Spuštění zítra v 11:00:
at 11:00 AM tomorrow
Spuštění příští týden ve stejný den v 11:00:
at 11:00 AM next week
Spuštění v tento čas, tento den příští týden:
at next week
Spuštění příští pátek v 11:00:
at 11:00 AM next fri
Spuštění příští pátek v tento čas:
at next fri
Spuštění v 11:00 v tento den, příští měsíc:
at 11:00 AM next month
Spuštění v 11:00 v konkrétní den:
at 11:00 AM 3/15/2020
Spuštění za 30 minut od teď:
at now + 30 minutes
Spuštění za dvě hodiny:
at now + 2 hours
Spuštění zítra v tento čas:
at tomorrow
Spuštění ve čtvrtek v tento čas:
at thursday
Spuštění o půlnoci:
at midnight
Spuštění v poledne:
at noon
Pokud jste Brit, můžete si dokonce naplánovat spuštění příkazu v době čaje (16:00):
at teatime
Zobrazení fronty úloh
Pro zobrazení fronty naplánovaných úloh použijte příkaz atq
, jak je uvedeno níže.
Pro každou úlohu ve frontě atq
zobrazí následující informace:
- ID úlohy
- Plánované datum
- Plánovaný čas
- Frontu, ve které se úloha nachází. Fronty se označují „a“, „b“ atd. Normální úlohy, které naplánujete pomocí
at
, jsou ve frontě „a“, zatímco úlohy naplánované pomocí příkazubatch
(popsaného dále) jsou ve frontě „b“. - Osoba, která úlohu naplánovala.
Použití at z příkazové řádky
Příkaz at
nemusíte používat jen interaktivně; můžete ho také použít v příkazech, což usnadňuje jeho využití ve skriptech.
Příkazy můžete zadat pro at
takto:
echo "sh ~/sweep.sh" | at 08:45 AM
Úloha je přijata a naplánována. Číslo úlohy a datum spuštění se zobrazí stejně jako dříve.
Použití at se soubory příkazů
Můžete také uložit posloupnost příkazů do souboru a předat ho příkazu at
. Může to být prostý textový soubor s příkazy – nemusí to být spustitelný skript.
Pro předání názvu souboru příkazu at
můžete použít volbu -f
(file) takto:
at now + 5 minutes -f clean.txt
Stejného výsledku můžete dosáhnout, pokud soubor přesměrujete do at
:
at now + 5 minutes < clean.txt
Odstraňování naplánovaných úloh z fronty
Pro odstranění naplánované úlohy z fronty můžete použít příkaz atrm
. Pokud chcete nejprve zjistit číslo úlohy, kterou chcete odstranit, použijte příkaz atq
. Potom použijte toto číslo úlohy s příkazem atrm
, jak je uvedeno níže:
atq
atrm 11
atq
Jak zobrazit podrobný pohled na úlohy
Jak již bylo zmíněno, úlohy je možné plánovat i s velkým předstihem. Někdy se vám může stát, že zapomenete, co má která úloha dělat. Příkaz atq
vám sice ukáže úlohy ve frontě, ale neřekne, co vlastně dělají. Pokud potřebujete detailní pohled na konkrétní úlohu, použijte volbu -c
(cat).
Nejprve pomocí atq
najdeme číslo úlohy:
atq
Nyní použijeme úlohu číslo 13 s volbou -c
:
at -c 13
Zde je rozpis informací, které o úloze získáte:
- První řádek: říká nám, že příkazy poběží v shellu
sh
. - Druhý řádek: vidíme, že příkazy budou spuštěny s ID uživatele a skupiny 1000. To jsou hodnoty pro uživatele, který spustil příkaz
at
. - Třetí řádek: uživatel, který obdrží případné e-maily.
- Čtvrtý řádek: uživatelská maska je 22. To je maska používaná k nastavení výchozích oprávnění pro soubory vytvořené v této relaci shellu
sh
. Maska se odečítá od 666, což nám dává 644 (oktalový ekvivalentrw-r--r--
). - Zbývající data: většinou proměnné prostředí.
- Výsledky testu. Test kontroluje, zda je možné přistupovat ke spouštěcímu adresáři. Pokud ne, dojde k chybě a provedení úlohy se ukončí.
- Příkazy, které se mají provést. Ty se vypíší a zobrazí se obsah skriptů, které jsou naplánované. Všimněte si, že i když byl skript v našem příkladu napsán tak, aby se spouštěl v Bash, bude spuštěn v shellu
sh
.
Příkaz batch
Příkaz batch
funguje podobně jako příkaz at
, ale s třemi zásadními rozdíly:
- Příkaz
batch
můžete použít pouze interaktivně. - Namísto plánování úloh pro konkrétní čas, jsou úlohy přidávány do fronty a příkaz
batch
je provede, když průměrné zatížení systému klesne pod hodnotu 1.5. - Z výše uvedeného plyne, že u příkazu
batch
nikdy neurčujete konkrétní datum a čas spuštění.
Při použití příkazu batch
ho zavoláte bez parametrů, například takto:
batch
Poté přidejte úlohy stejným způsobem jako u příkazu at
.
Řízení přístupu k příkazu at
Soubory at.allow
a at.deny
řídí, kdo může používat příkazy z rodiny at
. Tyto soubory se nacházejí v adresáři /etc
. Ve výchozím stavu existuje pouze soubor at.deny
, který se vytvoří při instalaci at
.
Funguje to následovně:
at.deny
: obsahuje aplikace a uživatele, kterým není povolené plánovat úlohy.at.allow
: obsahuje uživatele, kteří mohou plánovat úlohy pomocíat
. Pokud souborat.allow
neexistuje,at
používá pouze souborat.deny
.
Ve výchozím stavu může příkaz at
používat kdokoliv. Chcete-li omezit, kdo ho může používat, použijte soubor at.allow
, do kterého vypište uživatele, kteří mohou příkaz at
používat. Je to jednodušší, než přidávat do souboru at.deny
všechny uživatele, kteří příkaz používat nemohou.
Zde je obsah souboru at.deny
:
sudo less /etc/at.deny
Soubor obsahuje seznam součástí operačního systému, které nemohou používat příkaz at
. Mnohé z nich mají zabráněn přístup z bezpečnostních důvodů, a proto byste z tohoto souboru neměli nic odstraňovat.
Nyní upravíme soubor at.allow
. Přidáme uživatele dave
a mary
, a nikdo jiný nebude moci at
používat.
Nejprve zadejte:
sudo gedit /etc/at.allow
V editoru přidáme dva uživatele, jak je uvedeno níže, a soubor uložíme.
Pokud se někdo jiný pokusí at
použít, bude mu sděleno, že k tomu nemá oprávnění. Například, pokud uživatel jménem eric
zadá následující příkaz:
at
Bude odmítnut, jak je vidět níže.
Je potřeba znovu zdůraznit, že uživatel eric
není v souboru at.deny
. Jakmile vložíte kohokoli do souboru at.allow
, budou mít všichni ostatní zakázané oprávnění k používání příkazu at
.
Skvělé pro jednorázové úlohy
Jak vidíte, at
i batch
jsou ideální pro úlohy, které potřebujete spustit pouze jednou. Rychlé shrnutí:
- Pokud potřebujete provést něco, co není běžná operace, naplánujte si to pomocí
at
. - Pokud chcete spustit úlohu jen tehdy, když je zatížení systému dostatečně nízké, použijte
batch
.